什么是设计模式?
最后更新于:2022-04-01 11:45:31
# 什么是设计模式
一个模式就是一个可重用的方案,可应用于在软件设计中的常见问题 - 在我们的例子里 - 就是编写JavaScript的web应用程序。模式的另一种解释就是一个我们如何解决问题的模板 - 那些可以在许多不同的情况里使用的模板。 那么理解和熟悉模式为什么是如此的重要?设计模式有以下三点好处:
* 模式是行之有效的解决方法:他们提供固定的解决方法来解决在软件开发中出现的问题,这些都是久经考验的反应了开发者的经验和见解的使用模式来定义的技术。
* 模式可以很容易地重用:一个模式通常反映了一个可以适应自己需要的开箱即用的解决方案。这个特性让它们很健壮。
* 模式善于表达:当我们看到一个提供某种解决方案的模式时,一般有一组结构和词汇可以非常优雅地帮助表达相当大的解决方案。
模式不是一个确切的解决方案。我们要记住模式的角色仅仅是给我们提供一个解决方案。模式不能解决所有的设计问题,也不能代替优秀的软件设计师。然而,它们在帮助我们。接下来我们将看看模式必须提供的其他的一些优势。
* 模式的重用可以帮助防止在应用程序开发过程中出现的一些可能导致重大问题的小问题。这意味着当代码是建立在行之有效的模式上时,我们可以花更少的时间去关心我们的代码结构,从而能花更多的时间关注我们的解决方案的整体质量。这是因为模式可以鼓励我们在更好的结构化和有组织的方式下编码,这将避免在未来由于清洁的目的而去重构它。
* 模式可以提供一个不需要绑定到一个特定问题的书面的概括性的解决方案。这个广义的方法意味着不用管我们正在处理的应用程序 (许多情况下的编程语言) 设计模式的应用可以提高我们的代码的结构。
* 某些模式可以通过避免重复来减小我们代码的文件大小。通过鼓励开发者更仔细地看待他们的解决方案来减少重复的地方,如通过将类似的执行流程作为一个一般性的函数来减少函数的数量,这样我们就可以减小代码库的总体大小,这也成为使代码更DRY。
* 模式增加了开发者的词汇,这使得交流更快速。
* 经常使用的模式可通过收集其他使用这些模式的开发人员贡献给设计模式社区的经验来改进。在某些情况下,这将导致全新模式的创建,同时也可以提供改进的指导大家如何使用特定的模式才是最好的。这可以确保基于模式的解决方案继续变得比特别的解决方案更健壮。
## 我们已经每天都在使用模式
为了了解模式有多有用,让我们看看jQuery提供给我们的一个很简单的元素选择问题。 假设我们有一个为页面上每一个class为"foo"的DOM元素添加一个计数器的脚本,什么才是查询这个元素的集合的最有效的方法呢?有几种不同的方法可以解决这个问题:
选择页面上所有的元素并存储它们的引用,然后使用正则表达式 (或其他方式) 来过滤这个集合中那些class为"foo"的元素的引用。
* 使用像asquerySelectorAll()的现代原生浏览器的特性,来选择所有的class为"foo"的元素。
* 使用像asgetElementsByClassName()的原生特性同样可以获取期望的集合。
那些,这些选择哪个是最快的呢?实际上第三个,比其他的替代选择快 8-10倍。但在实际的应用程序中,第三个选择无法在Internet Explorer 9以下的版本中使用,从而只能使用第一个,第二个和第三个都不支持。
使用jQuery的开发人员就不必担心这个问题,因为很幸运的是它使用Facade模式把这个问题抽象了出来。正如我们即将在后面更详细的介绍的那样,这种模式提供了一组简单的对更复杂的底层代码的抽象接口 (例如$el.css(),$el.animate()) 。正如我们所看到的,这意味着我们只会对实现级别的细节花费更少的时间。
在其后,库会根据我们当前浏览器的支持自动选择最优的方法来选择元素,我们只使用抽象层。
我们可能都熟悉jQuery的$("selector"),这是更容易使用的在一个页面选择HTML元素的方法,这样我们就不必手动来选择getElementById(),getElementsByClassName(),getElementByTagName()等方法。
虽然我们知道querySelectorAll()试图解决这个问题,但比比使用jQuery的Facade接口和自己来选择最优的方式时花费的精力,毫无疑问,使用模式可以提供真实世界的抽象价值。
我们将在本书的后面看到更多的设计模式。
## “模式特性”测试,模式原型和三条规则
记住并不是每个算法、每个最佳实践和每个解决方案都可能被认为是一个完整的模式。这儿可能缺少了几个关键因素,而且模式社团除非经过严格的审查才谨慎地声明某东西为模式的。即使某东西对我们来说似乎满足了模式标准,它都不应该被当作模式,直到它由他人经过适当时间的周密调查和测试后才可能当作模式。
回头看看Alexander曾经做过的工作,他声明模式应当既是过程也是“事物”。这个定义故意不明确,因为他紧跟着说模式应该是创建“事物”的过程。这就是为什么模式通常集中定位在表面上可识别的结构的原因。例如,我们应当能够可视化地描绘(或者绘制)图片来展示把模式应用到实践中的结构。
在研究设计模式的时候,无意间碰到术语“模式原型”是很正常的。那么什么是模式原型呢? 好,仍然没有通过"模式特性”测试的模式通常认为是模式原型。模式原型也许源自于某人已经确定的值得与社团共享的特定解决方案的工作,然而由于它提出时间短,所以可能仍然没有机会接受严格的审查。
另外,个人共享的模式也许没有时间或者没有兴趣通过“模式特性”测试这个过程,不过可能发布了这些模式原型的简短说明。这种类型模式的简要描述或者片段就是众所周知的小模式。
全面文档化具有资格的模式这样的工作是非常令人气馁的。回头看看设计模式领域最早期的某些工作,如果一个模式能做到以下事情,那么这个模式就可以认为是“好的”模式:
* 解决一类特定的问题:模式不能假设仅仅关注原理或者策略。它们需要关注解决方案。这是好的模式最重要的因素之一。
* 问题的解决方案不是表面上的:我们发现解决问题的技术常常首先试图源自于某个众所周知的原理。最佳的设计模式通常间接地提供问题的解决方案-认为模式是与设计相关的最具有挑战性的问题必然的解决方法。
* 所描述的想法一定得到了证明:设计模式需要提供所描述的它们运行的证据,如果没有这些证据,就不会认真的考虑这个设计。如果模式事实上是高度理论性的话,那么只有冒险者才可能试着用它。
* 它必须说明与代码之间关系:在某些情况下,模式似乎说明了一种类型的模块。虽然实现的可能就是这个方法,但是官方的模式说明一定要更深入的描述系统结构和机制,以解释它与代码之间的关系。
我们认为不满足准则的模式原型不值得学习,这可以得到谅解,然而,事实远不是这样的。许多模式原型确实非常的好。我不是说所有的模式原型都值得看,不过总有几个在自然环境下成长的有用的模式原型可以在未来的项目中帮到我们。从心底里使用上面列表来做最佳评判的话,你在选择哪个是模式的过程中将感觉非常愉快。
模式是否有效的附加要求之一是模式要展示某些重现现象。这个就是至少在三个关键方面 ,也就是三条规则验证是否取得资格经常要做的事情。为了展示使用这个规则后的重现,模式必须证明其:
* 适用性-模式怎样才能被认为是成功的。
* 有用性-为什么认为这个模式是成功的?
* 可用性 -因为设计得到广泛的应用,所以认为这个设计就是模式吗?如果是这样的话,那么需要说明。重新审核或者定义模式的时候,牢记以上规则非常重要。