设计模式的七大设计原则和三大分类

2019-02-08

1 设计模式的七大原则

1.1 单一职责原则

通俗的讲就是一个类只负责一项职责。就一个类而言,应该仅有一个引起它变化的原因,增加功能不应该修改已有的代码,避免修改出错及重复测试。如果你能够想到多于一个的动机去改变一个类,那么这个类就是具有多于一个的职责, 应该考虑类的职责分离。

遵循单一职责原则的优点

  • 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
  • 提高类的可读性,提高系统的可维护性;
  • 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

1.2 里氏替换原则

通俗的讲就是子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下四层含义:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

1.3 依赖倒置原则

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
依赖倒置原则的核心思想是面向接口编程,主要是通过面对接口编程,将实现细节与业务逻辑分开,它们都是通过抽象的接口来完成交互的。业务逻辑只和抽象的接口打交到,而不必关注具体的实现过程。同样实现过程也不必关注业务,它只需要关注接口即抽象即可。
在实际编程中,我们一般需要做到如下3点:

  • 低层模块尽量都要有抽象类或接口,或者两者都有。
  • 变量的声明类型尽量是抽象类或接口。
  • 使用继承时遵循里氏替换原则。

1.4 接口隔离原则

客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
接口隔离原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
接口隔离原则和单一指责原则的区别

  • 单一职责原则原注重的是职责;而接口隔离原则注重对接口依赖的隔离;
  • 单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口接口,主要针对抽象,针对程序整体框架的构建。

采用接口隔离原则对接口进行约束时,要注意以下几点:

  • 接口尽量小,但是要有限度。接口如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度;
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系;
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

注意:运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。

1.5 迪米特法则

一个对象应该对其他对象保持最少的了解。由于类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。所以尽量降低类与类之间的耦合度。
通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,不是直接朋友的类最好不要作为局部变量的形式出现在类的内部。

1.6 开闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
开闭原则无非就是想表达:用抽象构建框架,用实现扩展细节。
说到这里,再回想一下前面说的5项原则,恰恰是告诉我们用抽象构建框架,用实现扩展细节的注意事项而已:

  • 单一职责原则告诉我们实现类要职责单一;
  • 里氏替换原则告诉我们不要破坏继承体系;
  • 依赖倒置原则告诉我们要面向接口编程;
  • 接口隔离原则告诉我们在设计接口的时候要精简单一;
  • 迪米特法则告诉我们要降低耦合。
  • 而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。

1.7 合成/聚合复用原则

能够使用合成/聚合的,不要使用继承。
合成是指局部与整体的关系,“整体”负责“部分”的生命周期,他们之间是共生共死的;并且“部分”单独存在时没有任何意义。如:People类与Soul类、Body类之间是组合关系,当人的生命周期开始时,必须同时有灵魂和肉体;当人的生命周期结束时,灵魂肉体随之消亡;无论是灵魂还是肉体,都不能单独存在,他们必须作为人的组成部分存在。
聚合则是包含的关系,他们之间是“整体-个体”的相互关系,如:People类与Car类、House类,People类可以由Car类和House类聚合。

2 设计模式的三大分类

2.1 创建型模式

共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

2.2 结构型模式

共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

2.3 行为型模式

共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。