设计模式七大原则详解

103 阅读6分钟

设计模式是面向对象分析和设计的非常重要的理念,目的是为了让程序具有以下更优秀的特性:

  • 代码复用性
  • 可读性
  • 可扩展性
  • 可靠性
  • 实现高内聚、低耦合的特性

设计模式遵循的七大原则:

  • 单一职责原则(Single Responsibility Principle,SRP)
  • 开闭原则(Open-Closed Principle,OCP)
  • 里氏替换原则(Liskov Substitution Principle,LSP)
  • 依赖倒置原则(Dependence Inversion Principle,DIP)
  • 接口隔离原则(Interface Segregation Principle,ISP)
  • 迪米特法则(Law of Demeter,LoD)
  • 合成复用原则(Composite Reuse Principle,CRP)

一、单一职责原则(Single Responsibility Principle,SRP)

一个类或一个方法只负责一项职责,只有一个引起它变更的原因。是实现高内聚、低耦合的指导方针,比如业务对象和业务逻辑拆分。

单一职责的优点:

  • 降低类的复杂度
  • 提高类的可读性、提高系统可维护性、提高可扩展性
  • 降低变更带来的风险

二、开闭原则(Open-Closed Principle, OCP)

开闭原则的特点:

  • 是编程中最基础、最重要的设计原则;
  • 模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方),用抽象构建框架,用实现扩展细节;
  • 当软件需要更新或变化时,尽量通过扩展软件的行为实现,而不是通过修改已有的代码实现变化。

在Java中,一般使用接口和抽象类实现,在实现的过程中注意以下方面:

  • 通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;
  • 参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;
  • 抽象层尽量保持稳定,一旦确定不允许修改。

三、里氏替换原则(Liskov Substitution Principle,LSP)

**继承在给程序设计带来便利的同时,也带来了弊端。**使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当该类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。

那么如何正确使用继承?=>里氏替换原则

里氏替换原则

  • 1988年,由麻省理工学院的一位姓里的女士提出的。
  • 如果对每个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。即所有引用基类的地方必须能透明地使用其子类的对象。
  • 使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的代码。
  • 继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合、组合、依赖来解决问题。

四、依赖倒置原则(Dependence Inversion Principle,DIP)

**依赖倒转原则是的设计理念:**相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类。

依赖倒置原则的特点

  • 中心思想是面向接口编程
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  • 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

五、接口隔离原则(Interface Segregation Principle,ISP)

接口隔离原则的特点

  • 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口 上
  • 类A通过接口 Interface1 依赖类B,类C通过接口 Interface1 依赖类D,如果接口 Interface1 对于类A和类C来说不是最小接口,那么类 B 和类 D 必须去实现他们不需要的方法。将接口 Interface1 拆分为独立的几个接口,类 A 和类 C 分别与他们需要的接口建立依赖关系,即采用接口隔离原则

六、迪米特法则(Law of Demeter,LoD)

迪米特法则的特点

  • 一个对象应该对其他对象保持最少的了解,如果类与类关系越密切,耦合度越大
  • **迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。**即对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部,对外除了提供的public方法,不对外泄露任何信息。
  • 核心是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)的耦合关系,并不是要求完全没有依赖关系。

七、合成复用原则(Composite Reuse Principle,CRP)

合成复用原则的特点

  • 原则是尽量使用合成/聚合的方式,而不是使用继承
    • 聚合用来表示“拥有”关系或者整体与部分的关系。代表部分的对象有可能会被多个代表整体的对象所共享,而且不一定会随着某个代表整体的对象被销毁或破坏而被销毁或破坏,部分的生命周期可以超越整体。例如,Iphone5和IOS,当Iphone5删除后,IOS还能存在,IOS可以被Iphone6引用。
    • 合成用来表示一种强得多的“拥有”关系。在一个合成关系里,部分和整体的生命周期是一样的。比如水和鱼的关系,当水没了,鱼也不可能独立存在。
  • 通过将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而达到复用。

八、总结

7种设计原则是软件设计模式必须尽量遵循的原则,各种原则要求的侧重点不同。

  • 开闭原则是总纲,告诉我们要对扩展开放,对修改关闭;
  • 里氏替换原则告诉我们不要破坏继承体系;
  • 依赖倒置原则告诉我们要面向接口编程;
  • 单一职责原则告诉我们实现类要职责单一;
  • 接口隔离原则告诉我们在设计接口时依赖关系建立在最小接口上;
  • 迪米特法则告诉我们要降低类之间的耦合度;
  • 合成复用原则告诉我们要优先使用组合/聚合方式,少用继承关系复用。

设计原则思想

  • 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  • 针对接口编程,而不是针对实现编程。
  • 为了交互对象之间松耦合设计而努力