我们将要使用的主要工具是重构(refactoring)。重构的目的不是增加新的功能,而是重写代码得它们更加清晰。更加清晰的代码本身就是一个令人满意的结果,但是除此之外,它还可以带来其他引人注目的好处,应该能够吸引那些在底线上苦苦挣扎、如必履薄冰的开发人员。
通常,如果代码经过了良好的重构,那么为它增加、修改或者去掉某些功能就会更加容易。这是因为代码很容易理解。相反,如果代码没有经过良好的重构,经常会出现,即使每一件事情都符合了当前的需求,但是开发团队仍然对于代码为何能够工作缺乏信心。
需求的变化总是要求在很短时间内就能实现,这已经是大多数专业编程工作中的一种常态。重构可以保持代码清晰,使它易于维护,允许你毫无畏惧地面对和实现需求的变化。重构的另一个动机是识别出通用的解决方案,并且按照这种特定的模式来重新组织代码。这样做本身同样可以使得代码更加令人满意,而且还可以带来非常实际的好处。遵循成熟模式的代码,更有可能得到满意的结果,这仅仅是因为在此之前别人已经做过这件事。与之相关的很多问题都已经经过了其他人的深思熟虑,并且如我们希望的那样,已经解决了。
这种行事方式有时候也称作设计模式(design pattern)。模式的概念诞生于20世纪70年代,当时用来描述建筑问题的解决方案,近十年来,软件开发领域借用了这种概念。设计模式仅仅是用来描述在软件设计中解决特定问题的一种可重复的方法。
跨浏览器不一致性:Facade模式和Adapter模式
产生原因:
浏览器厂商提供了非标准机制来获得XMLHttpRequest对象,用于发送异步请求到服务器。当要从服务器加载一个XML文档的时候,我们需要确定可以使用哪一个方法。IE只能通过访问ActiveX组件获得这个对象,而Mozilla和Safari则是以内建的原生对象的形式提供这个对象(IE7提供了原生对象),只有加载XML的代码本身需要知道这个差别。一旦XMLHttpRequest对象被返回给其余的代码,这个对象的行为在两种情况下都是相同的。调用它的代码即无须理解ActiveX,也无须理解原生的对象子系统。
解决方案:
Facade模式可以用来为一个服务或者一些功能的不同实现方式提供公共的访问点。Adapter模式就就是在微软和Mozilla的浏览器中得到一个XMLHttpRequest对象一样,是与两个提供相同功能的子系统共同工作。
管理事件处理函数:Observer模式
产生原因:
当使用JavaScript对DOM节点进行脚本处理的时候,通常都需要定义一个window.onload函数。这个函数会在页面(以及其所对应的DOM树)全部加载完成时候执行。当把所有的组合事件处理函数放在一起时会变得难以花困难而且极易出错。
解决方案:
在一个组合函数的解决方案中,window对象负责获得DOM元素的引用,随后window对象必须知道当前页面中包括哪能些子系统。理想情况下,每个子系统应该自己负责获取它们需要的引用。按照这种方式,如果它包括在页面中,就会获得自己需要的引用;如果没有包括在页面中,就不必做这件事情。
通过传递一个函数登记,从而发生onload事件时得到通知
window.onloadListeners = new Array();
window.addOnLoadListener(listener){
window.onloadListeners[window.onloadListeners.length] = listener;
}
窗口完全加载后,window对象只需要遍历这个数组
window.onload = function(){
for(var i=0;i<window.onloadListeners.length;i++){
var fun = window.onloadListeners[i];
fun.call();
}
}
如果每一个子系统都使用这种方法,我们就可以提供更清晰的方式来设置所有的子系统,而不必将它们混杂在一起。Observer模定定义一个Observable对象,在例子中它是内建的window对象,一组Observer或Listener可以将自己登记在这个对象上。通过Observer模式,职责被适当地分配到了事件源和事件处理函数之间。处理函数负责它们自己的登记或取消登记,事件源则负责维护已登记的列表,并且在事件发生时通知它们(Observer模式的事件驱动用户界面编程领域已拥有悠久的使用历史)。
重用用户操作处理函数:Command模式
产生原因:
在大多数应用中,都是由用户来告诉(通过点击鼠标和按下键盘)应用程序要做些什么事情,然后应用程序照着做,这可能是一件显而易见的事情。在一个简单程序中,可能只会给用户提供一种方法来完成一个操作,但在更加复杂的界面中,我们常常想让用户通过几种途径来解发相同的操作。
解决方案:
Command模式定义了一些具有任意复杂性的活动,可以很容易地在代码之间传递,或者在UI元素之间交换。在面向对象语言的传统Command模式中,用户的交互都封装为Command对象,通常继承自一个基类或者实现一个接口。将用户所做的事情都封装为Command对象可能看起来有点麻烦,但是这样做是有回报的。当所有的用户行为都封装在Command对象中时,我们就可以很容易地联合使用其他标准的功能。
保持对资源的唯一引用:Singleton模式
产生原因:
在实际应用中,有些应用需要内存中的对象唯一,也就是所有的应用都调用唯一的资源,这样所有的应用实际上同步了它们的数据。
解决方案:
在JavaScript中,虽然没有内建的对于访问修饰符的支持,但是可以通过不提供构造函数的方式来“隐藏”构造函数。JavaScript是基于原型的,构造函数是变通的function对象。
模型-视图-控制器
模型-视图-控制器(MVC)描述的是将程序与用户交互的部分和完成其他繁重工作、科学计算或业务逻辑等等的部分很好分离的一种方式。MVC的黄金定律是视图和模型不应该相互通信。当用户按下一个按钮或者填写一个表单时,视图会通知控件器。控制器操作模型并且决定模型上的变化是否需要变化视图。

没有评论:
发表评论