第 7 章 创建设计模式

设计模式是针对重复出现的问题的可重用解决方案。 该术语的定义非常广泛,可以跨越应用程序的多个领域。 然而,这个术语通常与一组著名的面向对象模式联系在一起,这些模式在 90 年代通过 Pearson Education 的《设计模式:可重用面向对象软件的元素》一书而流行起来,作者是近乎传奇的四人帮 (GoF) :埃里希·伽玛、理查德·赫尔姆、拉尔夫·约翰逊和约翰·弗利塞德斯。 我们经常将这些特定的模式集称为传统设计模式或 GoF 设计模式。

在 JavaScript 中应用这套面向对象设计模式并不像在经典面向对象语言中那样线性和形式化。 众所周知,JavaScript 是面向对象的、基于原型的,并且具有动态类型。 它还将函数视为一等公民,并允许函数式编程风格。 这些特性使 JavaScript 成为一种非常通用的语言,它为开发人员提供了巨大的力量,但同时,它也导致了编程风格、约定、技术以及最终其生态系统模式的碎片化。 对于 JavaScript,有很多方法可以实现相同的结果,以至于每个开发人员对于解决问题的最佳方法都有自己的看法。 JavaScript 生态系统中大量的框架和固执己见的库就清楚地证明了这种现象; 可能没有其他语言见过如此之多,尤其是现在 Node.js 为 JavaScript 提供了新的惊人的可能性,并创造了如此多的新场景。

在这种情况下,JavaScript 的本质也会影响传统的设计模式。 在 JavaScript 中实现传统设计模式的方法有很多种,以至于传统的、强面向对象的实现不再适用。

在某些情况下,这些设计模式的传统实现甚至是不可能的,因为正如我们所知,JavaScript 没有真正的类或抽象接口。 然而,不变的是每个模式的最初想法、它解决的问题以及解决方案的核心概念。

在本章和接下来的两章中,我们将看到一些最重要的 GoF 设计模式如何应用于 Node.js 及其哲学,从而从另一个角度重新发现它们的重要性。 在这些传统模式中,我们还将了解一些诞生于 JavaScript 生态系统本身的 “不太传统” 的设计模式。

在本章中,我们将特别了解一类称为创建型的设计模式。 顾名思义,这些模式解决与对象创建相关的问题。 例如,工厂模式允许我们将对象的创建封装在函数中。 Revealing Constructor 模式允许我们仅在对象创建期间公开对象的私有属性和方法,而 Builder 模式则简化了复杂对象的创建。 最后,单例模式和依赖注入模式帮助我们在应用程序中连接模块。

本章以及接下来的两章假设您对 JavaScript 中继承的工作原理有一定的了解。 还请注意,我们经常使用通用且更直观的图表来代替标准 UML 来描述模式。 这是因为许多模式不仅可以基于类,还可以基于对象甚至函数来实现。