坚实的基础对任何应用程序来说都至关重要。在写代码之前,必须先对应用程序的架构加以规范。程序有什么功能,将会如何实现?更重要的是这些功能彼此之间如何协作,换句话说,程序的体系是什么样的? 要回答这些问题,需要搞研究、做原型,并有坚实的最佳实践基础。尽管我不能帮你研究或实现程序中某些组件的原型,但我可以把从最佳实践中取得的经验传授给你。 本章介绍了松耦合的基本工程概念,详细解释了一个实现松耦合的办法:JavaScript MVC和模板引擎。之后介绍一些开发工具,比如Weinre、版本控制和CSS预处理。最后介绍如何在项目中设置Grunt、让文件合并和最小化之类的工作实现自动化处理。用Grunt可以确立测试驱动开发的模式,无论什么时候修改了文件,都会让程序通过一组测试。 1.1 松耦合 如果本书只能让你在一件事上受益,我希望你能从中学会如何避免在程序中出现紧耦合。紧耦合是一个古老的工程术语,指不同组件之间的交叉依赖关系太强了。比如说你买了台电视,这台电视还内置了一台蓝光播放机。但如果电视坏了会怎么样?蓝光播放机可能还完好无损,可以正常工作,但电视一旦坏了,就不能显示画面了。从工程角度来看,最好是避免这种紧耦合的情况出现,而采用独立的、外置的蓝光播放机。 这种模式对软件开发也适用。设计应用程序时基本上应该用功能单一、相互独立的模块。通过解耦这些任务,可以将不同模块之间的依赖程度降到最低。这样可以尽可能地让每个模块保持“单纯”,能够专注于单一任务,不用考虑跟程序中其他代码之间的关系。 但决定把哪些任务分组到一个模块中可能是一个挑战。可惜这个问题没有一个放之四海而皆准的解决方案:模块太少会导致耦合度太高,模块太多又会造成不必要的抽象。最好的办法是折中:在程序中使用数量合理、内聚程度高的模块。内聚程度高的模块就是把处理单一、明确任务的相关功能组合到一起。 1.1.1 紧耦合的问题 紧耦合的例子在我们身边随处可见。如果你跟我一样,那你应该也已经用手机取代了音乐播放器、电子游戏机,甚至手电筒。把这么多功能集成在一个简单的设备上肯定很方便。在这种情况下,紧耦合是有意义的。但这也意味着可能会出现连锁反应,如果一个东西出了问题,其他东西也会出问题,比如你用手机听了很长时间音乐后,可能会突然发现手电筒电量不足了。 软件开发中的紧耦合也不一定都是坏事,缺乏设计的耦合才更糟糕。应用程序中几乎总会有一些依赖关系,关键是要避免在互不相干的任务间出现不必要的耦合。如果你不努力隔离出不同的模块,就会得到一个脆弱不堪的程序,很可能会因为一个小bug彻底崩溃。当然,你肯定会想尽一切办法避免出现bug,但如果每个bug都能搞垮整个程序,你也无能为力。 另外,调试一个紧耦合的程序极其困难。当程序整个都瘫痪时,几乎不可能准确定位到最先出现bug的地方。这个问题就源自常说的空心粉式代码。跟一堆空心粉一样,代码的脉络相互交织在一起,很难把它们分开。 1.1.2 松耦合的优势 即便你很少遇到bug,松耦合仍然有些值得称道的优势。构建松耦合程序的一个主要原因实际上可以追溯到另一个经典的工程基础理念:可更换的部件。生产过程中经常要重新构建程序中的某些部分。如果谷歌开始对它的翻译API收费了,最好换成其他的。如果有个组件扩展性很差并在负载增加后越来越慢了,最好重新构建它。 如果程序耦合太紧密,一个模块中的变动就可能引发连锁反应,所有依赖模块都必须进行调整以适应这个变化。松耦合的程序可以避免这种额外的开发投入,把修改代码的影响限定在各自的模块内。 另外,松耦合也使得跟其他开发人员的协作更容易。如果所有组件都互不相干,就更容易实现并行工作。所有开发人员都可以放心大胆地完成自己的开发任务,而不用担心会破坏别人做的东西。 最后一点,松耦合的程序测试起来也更容易。如果程序的每一部分都处理一个单独、具体的任务,很容易设置单元测试来确保这些任务在任何情况下都能正确执行。本章后续内容中对单元测试有更多的介绍。 理想情况下,代码永远都不需要重构。但即便你能考虑到所有可能的情景,现实情况中也总有无法预见的问题出现,所以为什么要大费周章呢?试图提前解决问题会导致“过早优化”,肯定会拖慢开发速度。按照敏捷开发的理念,开发人员应该只关心眼前的问题,将来的问题将来再解决。松耦合可以精简敏捷开发过程,让代码库可以随着条件的改变自然发展。
JavaScript编程实战——1.1 松耦合
书名: JavaScript编程实战
作者: [美] Jon Raasch
出版社: 人民邮电出版社
原作名: JavaScript programming: pushing the limits
译者: 吴海星
出版年: 2014-3
页数: 320
定价: 59.00
装帧: 平装
ISBN: 9787115345486