何为模块化开发与按需加载
何为模块化开发?
为了回答这个问题,首先要解释何为“模块(module)”:
“模块是为完成某一功能所需的一段程序或子程序。模块是任何鲁棒的应用架构不可缺少的一部分,是系统中职责单一且可替换的部分。”以上定义中最为关键的两点是“职责单一”和“可替换”,这也是模块最基本的属性。
所谓模块化就是指把系统代码划分为一系列职责单一,且可替换的模块。模块化开发就是指如何开发新的模块,和复用已有模块来实现应用的功能。
何为按需加载?
按需加载需要从时间和空间两方面理解。
空间上:只加载当前页面需要的模块。
时间上:只有当用户表现出需要某一功能的意图时,才去加载相关模块。
模块化开发与按需加载的适用场景
满足如下条件的应用适合采用模块化开发与按需加载技术:
- 1. 应用复杂。系统拥有不止一个功能部分,这些部分可能共享一些底层代码。
- 2. 需要长期维护。开发初期可能需求不是十分明确,需要通过不断迭代的方式来开发。而且经常面临需求变更和功能添加。
- 3. 对性能要求苛刻。面临复杂的用户交互和数据展现问题。
传统的js开发模式和加载模式是怎样的?
在过去由于应用复杂度不高,JavaScript之于web页面一直处于一种辅助程序的地位,甚至谈不上是一门应用开发语言。而且多数网站都是一次性应用,规模较小,相对于可维护性,开发速度更重要。与其重构一个现有应用,还不如重写一个。在这样的环境下,采用传统的面向过程的编程模式足以应付开发需要。
由于网站规模较小,与其把代码划分为一系列小的模块,然后在不同页面中分别加载,还不如把相关代码都集中写在一处,比如写一个common.js 或 share.js,然后所有页面都引用这个文件。这样做开发简单,而且由于浏览器有缓存,首次加载后,后续加载无需网络传输,在性能也不会有什么大问题。
但如果我们要做的是一个大型web应用,以上开发模式就会暴露出严重的问题。
传统开发模式的问题。
- 问题一:由于代码的组织的结构是非模块化的,所以代码无法复用,进而导致代码重复,这就为维护埋下了隐患 – 需求变更或功能添加将导致代码多处更改,随着应用规模的增大,代码将迅速进入难以维护的状态。
- 问题二:由于代码粒度太大,页面可能会加载大量根本用不到的代码,即便忽略网络传输的问题,过多无用代码,也会导致页面解析缓慢。
- 问题三:由于所有代码都混在一起,无法测试,我们也就无法获得保证代码质量的有效手段。
为什么需要模块化开发与按需加载
可维护性的需要
代码的可维护性的一种理解是,新功能的添加无需修改已有代码,旧有功能的变更无需修改多处代码。
对于初期需求不明确,需要采用不断迭代方式开发的项目,代码可维护性就显的尤为重要。
可测性的需要
代码的可测性的一种理解是,代码可以在系统环境外进行独立正确性验证。在系统环境外对代码进行测试十分重要,这不仅能保证代码的正确性,同时也保证了代码可以在不同环境中复用。
性能的需要
模块化的代码可以实现按需加载,进而保证了我们不会把宝贵的页面加载时间浪费在下载和解释多余的代码上。
架构的需求
架构的任务之一是保证系统可以应对未来的变化。这些变化包括新功能的添加,原有功能的修改,地层库文件的更换(有jQuery切换到tangram或其他),性能优化等等。任何可以实现这一目标的架构都要求代码必须是模块化的。
代码复用
代码复用不仅仅是为了节省开发时间,同时也是保证代码质量的有效手段,代码的复用程度越高,其质量就越容易得到保证。多人协作的需要。
大型应用无法通过一人之力完成,多人协作是不可避免的。在多人协作的环境下,经常要面临修改或使用别人写的代码的问题。只有那些功能单一,接口明确,模块化代码我们才敢放心大胆的修改或使用。
模块化开发的理论基础
模块化开发是任何大型应用都必须采用的开发模式,同其他应用程序的开发一样,要实现JavaScript模块化开发,开发者必须了解如下理论基础。
《JavaScript语言精粹》 《object oriented javaScript》
- A) 单例模式。单例模式是指在程序运行期间保证一个类只有一个实例。由于JavaScript没有类的概念,应用单例模式其实就是保证我们的程序在运行期间,某一功能对象一直只是同一个对象,而不是每次都重复创建。
- B) 订阅者模式。这是JavaScript中应用最为广泛的模式。我们通过addEventListener或attachEvent为dom节点添加事件监听,其实就是在应用订阅者模式。订阅者模式通过让一组对象去监听一个对象的事件,实现对象间一对多的通信,在最大程度上降低了对象间的耦合度。
- C) 外观模式。外观模式通过将一个或一组对象的接口封装起来,对外只提供其他代码需要的接口,实现降低代码耦合度的任务。
更多内容可以参考《JavaScript设计模式》
如何实践 – 思想观念上
观念的转变
首先,我们要转变观念。我们是在做应用程序而不是在做页面,只有承认自己是在做应用程序,我们才可能在开发过程中想到这些问题:
- 1) 是否应该采用面向对象技术来组织代码,并且恰当的使用各种设计模式。
- 2) 是否应该采用一种合适架构模式,比如MVC。
- 3) 是否应该写单元测试。
- 4) 是否应该采用测试驱动开发的方式来编写代码。
- 5) 我的代码是否可以测试,并且容易维护。
- 6) 是否已为将来可能需要扩展的环节留出接口,事件或者回调函数。
- 7) 我的代码是否满足“单一职责”,“开放关闭”,“依赖倒转”等面向对象基本原则。
模块化的角度去思考问题
拿到一个需求时,不要急于实现它,而是先看看这个需求能否分解为几个小的需求。横向上,可以将一个大功能分解为一些小的功能点,而这些小的功能点很有可以在系统的不同环节中重复出现。纵向上我们可以任务逐层向下委托给其他模块。
写代码过程中:
当你发现自己正在写的代码之前可能写过是,就应该重构原有代码,提出可以复用的模块,然后在现有问题域中直接使用,而不是把相关的代码直接copy过来。
当你发现自己正在写的代码很具有通用性时,就应该考虑写一个模块,并再模块中注明使用方法,和适用场景,然后通知你的同事以后有类似需求可以直接使用这个模块。
如何实践 – 技术上
- 1. CommonJS。JavaScript没有内建的模块支持,而CommonJS规范给出了完整的JavaScript实现模块的方式。
- 2. 前端支持。有大量成熟的js按需加载框架可以使用,这里推荐seajs。详细内容见“参考资料”。
- 3. 后端支持。模块化的代码上线前需要进行打包压缩,打包过程需要通过对源码进行静态分析来获得模块间的依赖关系,进而将相关模块打包在一起。Seajs提供的spm工具可以自动完成这一个工作。
参考资料
欢迎转载,但请保证转载后内容排版美观、易读,且保留本文连接:
http://kingzs70.github.io/blog/2011/12/12/javascript_modulized_develop_and_requre_in_need