前序

设计模式是基于面向对象编程( OOP )来说的,设计模式原则是对于把代码设计成一定模式所遵循的公共意识规范。

代码设计本质上是逻辑划分问题。设计出合理的逻辑结构,让代码在可维护性、可扩展性、可复用性得到更好的提升,最终反应在综合成本的降低。

可维护性:在项目交接时,这点体现特别明显。可维护性上体现下面几点:

  1. 可读性(是否有合理的注释、代码风格等编程规范);
  2. 代码设计的合理,能否让别人快速理解代码结构,并着手新功能的开发;

可扩展性:这一点也可以作为可维护性的一部分,即是否可方便的添加新功能,同时不影响以前的功能;

可复用性:代码是否被合理封装。既不会毫无封装,也不会过度封装;

前置概念

抽象:在 Java 中,抽象便是接口和抽象类。由于是语法特性,如果代码尝试直接实例化接口或抽象类,编译器会直接报错。在 Javascript 中,没有这样的语法特性,但是这一点在 Typescript 中得到弥补。

无论是 Java 的抽象特性,还是因为 Javascript 不足出来的 Typescript,都是为了提高代码的质量。在软件工程中,基本思想是防止人为失误,导致不必要的成本损失

单一职责原则

Single Responsibility Principle,就如同字面意思一样,一个类或者模块的职责要单一。

开闭原则

Open - Close Principle,软件实体(类、模块、函数等)对扩展开放,对修改关闭。也就是说这样设计允许用户去扩展其的行为,而不能修改源代码。

我们在设计好功能模块后,假如用户在使用你的模块发现它并不满足基本功能的其它需求,那么这个模块本身设计来说就缺乏可扩展性,缺少为因需求改动而具备扩展接口。

里氏替换原则

Liskov Substitution Principle,父类能够被子类替换,程序的行为不受影响。这更像是验证复用性是否可靠。

迪米特法则

Law of Demeter,也可以叫 最少知道原则,即是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

比喻

去店里买东西,我们将钞票拿给收银员,而非是将钱包丢给收银员。

接口隔离原则

Interface Segregation Principle,客户端不应该强行依赖它不需要的接口,类与类之间的依赖关系应该建立在最小的接口上。

依赖倒置原则

Dependence Inversion Principle,这条在对软件进行抽象时需要考虑的原则。

基本思想:

  1. 高层模块不应该依赖低层模块;
  2. 他们都应该依赖于抽象;
  3. 抽象不应该依赖于细节;
  4. 细节应该依赖于抽象;

例子

问题:业务模块连接数据库的时候,假如之前直接使用 SQLServer 数据库来连接,现在需要改为 MySQL数据库。在没有抽象的情况下,我们需要修改所有业务模块使用 SQLServer 对象的地方,改成 Mysql 对象。

解决:这里需要明确业务模块是我们的高层模块,而数据库连接模块低层模块。套用原则,需要数据库连接(底层模块)创建(依赖)接口(抽象),并且数据库类(底层模块)实现(依赖)该接口(抽象),业务模块(高层模块)调用(依赖)数据库类实现的接口(抽象)方法。

合成复用原则

Composite Reuse Principle,这条原则在复用性提出了要求。在继承复用组合复用上,优先使用组合方式去复用。

总结:对于模块的设计者来说,需要花费精力集中在用户需求上,从而更能知道如何提取抽象。