# 何为设计模式
说起设计模式很多人就以为设计模式就是那 23 种设计模板,设计思路。其实不是的。在我看来设计模式应该把设计与模式拆分开来看待。设计是设计,指用按某种思路、原则或标准去实现功能达到目的。我将其称之为方法。而模式,指实现功能、达到目的的手段,是在设计原则指导下用以具体实操的手段。设计是方法、原则,模式是手段、实现。就如 ECMAScript 和 Javascript 的关系。23 种设计模式本质上就是在编程语言抽象能力不足的情况下,应对某些场景的最佳实践。
# 设计原则
设计原则有很多,有不同分类。设计原则并不是不可违背的,就像有时候为了性能不得不牺牲代码可读性一样,是否遵循某条设计原则取决于我们对目标收益的衡量。
现在大多数的设计原则都是基于面向对象的思想提出的。所以其对面向对象有非常强的指导性,但这并不表示只有面向对象才适用这些设计原则。
既然讲到了设计原则,那么就必须讲讲最流行的 SOLID 设计的原则。SOLID 意思为固体,但是它其实是五个原则缩写而成。
# Single Responsibility Principle
S:单一职责原则(Single Responsibility Principle)。单一职责原则简称 SRP ,顾名思义,就是一个类只负责一个职责。一个程序或者一个类就只负责做好一件事,把这件事情做到极致。功能过于复杂的就将其拆分开,各个部分保持独立,不依赖外部,以便后面可以组合。这种思路就类似于当今的流水线、各国的全球化分工、前后端分离。
# Open / Closed Principle
O:开放封闭原则(Open / Closed Principle)。开放封闭原则简称 OCP,它的开放指对扩展保持开放,封闭指对修改保持封闭,即可扩展 (extension),不可修改 (modification)。所谓对扩展开放就是若想要扩展一个类的功能,应该是开放的、容易的。而想要修改原有功能是封闭的、困难的。该规则的 “封闭” 部分规定,一旦模块被开发和测试完成,代码被修改的原因应该只有修复 bug 这一种情况。 “开放” 部分说,您应该能够扩展现有代码(而不是修改之前的代码)以引入新功能。与 SRP 一样,该原理通过限制对现有代码的更改来降低引入新错误的风险。
# Liskov Substitution Principle
L:里氏替换原则(Liskov Substitution Principle)。里氏替换原则简称 LSP,它强调的是一个对象在其出现的任何地方,都要可以用子类的实例做替换,而程序不出错。即子类可以覆盖父类的所有功能。父类能干的,子类要都能干。子类能干父类却不一定能干。这个原则是与面向对象语言的 继承 特性密切相关的。LSP 原则最重要的一点就是:避免子类重写父类中已经实现的方法。这就是 LSP 原则的本质。子类应该避免对父类方法进行重写,如果需要增加个性化,就应该对父类进行扩展,而不是重写,否则也会违背 OCP 原则。
# Interface Segregation Principle
I:接口隔离原则(Interface Segregation Principle)。ISP 表示接口应该保持单一独立,维持单一职责。这一点和 SRP 类似,但其不同之处是 ISP 强调一个类对另外一个类的依赖性应当是建立在最小的接口上的,达到最小依赖性。这一点是以 SRP 为基础。它还强调客户端不应该依赖它不需要的接口。如果一个类实现一个接口,但这个接口中有它不需要的方法,那么就需要把这个接口拆分,把它需要的方法提取出来,组成一个新的接口让这个类去实现,这就是接口隔离原则。简而言之,就是说,接口中的所有方法对其实现的子类都是有用的。否则,就将接口继续细分。可以把 ISP 理解为 SRP 的强化版。
# Dependency Inversion Principle
D:依赖倒置原则(Dependency Inversion Principle)。DIP 强调高级模块不应该依赖于低级模块,两者都应该依赖于抽象。抽象不应该依赖于细节。细节应该依赖于抽象。什么意思呢?简而言之就是要多用接口、针对接口编程,而不是针对具体实现细节编程。类似于学习中我们要针对概念进行学习、理解,最终的目的是理解抽象的概念。而不是去背诵对概念的文字描述、定义。