一个模式就是一个可重用的方案,可应用于在软件设计中的常见问题 - 在我们的例子里 - 就是编写JavaScript的web应用程序。模式的另一种解释就是一个我们如何解决问题的模板 - 那些可以在许多不同的情况里使用的模板。 那么理解和熟悉模式为什么是如此的重要?设计模式有以下三点好处:
模式不是一个确切的解决方案。我们要记住模式的角色仅仅是给我们提供一个解决方案。模式不能解决所有的设计问题,也不能代替优秀的软件设计师。然而,它们在帮助我们。接下来我们将看看模式必须提供的其他的一些优势。
为了了解模式有多有用,让我们看看jQuery提供给我们的一个很简单的元素选择问题。 假设我们有一个为页面上每一个class为"foo"的DOM元素添加一个计数器的脚本,什么才是查询这个元素的集合的最有效的方法呢?有几种不同的方法可以解决这个问题:
选择页面上所有的元素并存储它们的引用,然后使用正则表达式 (或其他方式) 来过滤这个集合中那些class为"foo"的元素的引用。
那些,这些选择哪个是最快的呢?实际上第三个,比其他的替代选择快 8-10倍。但在实际的应用程序中,第三个选择无法在Internet Explorer 9以下的版本中使用,从而只能使用第一个,第二个和第三个都不支持。
使用jQuery的开发人员就不必担心这个问题,因为很幸运的是它使用Facade模式把这个问题抽象了出来。正如我们即将在后面更详细的介绍的那样,这种模式提供了一组简单的对更复杂的底层代码的抽象接口 (例如$el.css(),$el.animate()) 。正如我们所看到的,这意味着我们只会对实现级别的细节花费更少的时间。
在其后,库会根据我们当前浏览器的支持自动选择最优的方法来选择元素,我们只使用抽象层。
我们可能都熟悉jQuery的$("selector"),这是更容易使用的在一个页面选择HTML元素的方法,这样我们就不必手动来选择getElementById(),getElementsByClassName(),getElementByTagName()等方法。
虽然我们知道querySelectorAll()试图解决这个问题,但比比使用jQuery的Facade接口和自己来选择最优的方式时花费的精力,毫无疑问,使用模式可以提供真实世界的抽象价值。
我们将在本书的后面看到更多的设计模式。
记住并不是每个算法、每个最佳实践和每个解决方案都可能被认为是一个完整的模式。这儿可能缺少了几个关键因素,而且模式社团除非经过严格的审查才谨慎地声明某东西为模式的。即使某东西对我们来说似乎满足了模式标准,它都不应该被当作模式,直到它由他人经过适当时间的周密调查和测试后才可能当作模式。
回头看看Alexander曾经做过的工作,他声明模式应当既是过程也是“事物”。这个定义故意不明确,因为他紧跟着说模式应该是创建“事物”的过程。这就是为什么模式通常集中定位在表面上可识别的结构的原因。例如,我们应当能够可视化地描绘(或者绘制)图片来展示把模式应用到实践中的结构。
在研究设计模式的时候,无意间碰到术语“模式原型”是很正常的。那么什么是模式原型呢? 好,仍然没有通过"模式特性”测试的模式通常认为是模式原型。模式原型也许源自于某人已经确定的值得与社团共享的特定解决方案的工作,然而由于它提出时间短,所以可能仍然没有机会接受严格的审查。
另外,个人共享的模式也许没有时间或者没有兴趣通过“模式特性”测试这个过程,不过可能发布了这些模式原型的简短说明。这种类型模式的简要描述或者片段就是众所周知的小模式。
全面文档化具有资格的模式这样的工作是非常令人气馁的。回头看看设计模式领域最早期的某些工作,如果一个模式能做到以下事情,那么这个模式就可以认为是“好的”模式:
我们认为不满足准则的模式原型不值得学习,这可以得到谅解,然而,事实远不是这样的。许多模式原型确实非常的好。我不是说所有的模式原型都值得看,不过总有几个在自然环境下成长的有用的模式原型可以在未来的项目中帮到我们。从心底里使用上面列表来做最佳评判的话,你在选择哪个是模式的过程中将感觉非常愉快。
模式是否有效的附加要求之一是模式要展示某些重现现象。这个就是至少在三个关键方面 ,也就是三条规则验证是否取得资格经常要做的事情。为了展示使用这个规则后的重现,模式必须证明其: