设计模式有六大设计原则

  • 单一职责原则 (Single Responsibility Principle)
  • 开闭原则 (Open-Closed Principle)
  • 里氏替换原则 (Liskov Substitution Principle)
  • 依赖倒置原则 (Dependence Inversion Principle)
  • 接口隔离原则 (Interface Segregation Principle)
  • 迪米特法则(Law Of Demeter)

23种设计模式,都是基于这些原则设计。

1、单一职责原则

英文名称: Single Responsibility Principle, 简称: SRP
单一职责原则要求一个接口或类只有一个原因引起变化,也就是说一个接口或一个类只有一个原则,它就只负责一件事(官话)
换句话说就是只干自己的事,也就是一个类或者接口只实现或者定义自己职责范围类的方法,不要冗余其他动作。这样能让代码复杂性降低,从而提高代码的可读性和可维护性。单一职责原则不仅适用于接口和类,同样适用于方法,甚至整个类库。
对于这个原则,最大的难处就是对于职责的划分,在具体业务中,还要根据实际情况来界定。其实我觉得也不要在任何情况下都要一味的满足该原则,在实际业务下,多方面考虑,比如工期、成本、人员技术等多方面。择优选择未必不比这个死的原则要好得多。

2、里氏替换原则

英文名称: Liskov Substitution Principle, 简称: LSP
任何使用基类的地方,都可以透明的使用子类(官话)
白话理解就是:父类的东西不要去修改或者覆盖。你可以有自己的个性,有自己独有的方法或其他东西,但是老祖宗的东西你最好不要动。
这样做的好处就是: 父类的功能永远是清晰和固定的,用子类实例调用相同功能时,也会产生同样结果,不会因为子类覆盖搞得乱七八糟,避免埋雷。

3、依赖倒置原则

英文名称: Dependence Inversion Principle, 简称: DIP
高层模块不依赖于低层模块,二者都依赖其抽象。依赖抽象,不依赖细节。(官话)
总结来说,就是写代码的时候尽量通过抽象来减少各个模块之间的依赖,主要表现如下:

  • 实现类尽量都要有自己的接口或者抽象类,或者两者都有
  • 我们在使用这个类实例的时候使用其实现的接口或者抽象类来实例化,如 Animal dog = new Dog(); (dog实现抽象类Animal)
  • 当别的功能模块使用当前类时, 也通过抽象类进行依赖。比如我们定义一个接口方法(Eat)时,需要传入上面的动物(Dog),那么写作 void Eat(Animal animal); 而不是 void Eat(Dog dog);

遵循依赖导致原则是使用依赖注入的关键, 同时也有利于降低代码之间的耦合度,提高可扩展和可维护性。

4、接口隔离原则

英文名称: Interface Segregation Principle, 简称: ISP
接口隔离原则又被称为最小接口原则,就是说我们在为实现类定义接口的时候, 在保证单一职责的前提下, 尽可能的按业务功能将接口功能定义细化,也就是让接口本身是高内聚的状态,让接口只描述自己相关的事情。
接口隔离听起来和单一职责原则很相似,他们区别如下(来自网上):

接口隔离原则和单一职责原则很相似,它们的区别在于观察角度不一样。单一职责是从模块、类或方法自身的角度来看的,接口隔离原则是从调用者的角度来看的。举个例子,有个聚合服务,为APP提供了一组相同标准的接口,但它们的功能不同,有些和商品相关,有些和用户相关,有些和订单相关。这看起来既不符合接口隔离原则,也不符合接口单一职责原则。其实,从APP的角度来看,这组接口是一个整体,多一个不行,缺一个不可,所以它是符合接口隔离原则的。从更粗粒度的服务层面来看,这个聚合服务本身只为APP服务,这也符合单一职责。

5、迪米特法则

英文名称: Law of Demeter, 简称: LOD
迪米特法则又被称为最少知道原则,就是说

  • 一个类保持对其他类最少了解
  • 类只与直接朋友通信,对于间接朋友,当由间接朋友的直接朋友来实现类之间的通信。

其实迪米特法则表达的就是类之间的低耦合度,不要让类之间的依赖复杂化。 低耦合度能提高代码的可维护性,不会导致牵一发而动全身尴尬。但是解耦也是要有限度的,无限制的解耦也会导致得不偿失。
直接朋友: 包括方法返回值类型,输入变量类型,类成员类型。 如下B、B1是A的直接朋友:

  1. // 第一种
  2. class A{
  3. private B b;
  4. private B1 b1 {get; set;}
  5. }
  6. // 第二种
  7. class A{
  8. public void hello(B b){
  9. }
  10. }
  11. // 第三种
  12. class A{
  13. public B hello(){
  14. }
  15. }

间接朋友: 局部变量。 如下,B是A的间接朋友

  1. class A{
  2. public hello(){
  3. B b=new B(); //B是陌生的类
  4. }
  5. }

由上面的直接朋友和间接朋友其实也应该知道: 迪米特法则其实也是在说自己的逻辑封装自己的内部,外部不要了解具体细节,外部只需要进行简单调用即可。这也是一种解耦的提现。

6、开闭原则

英文名称: Open-Closed Principle, 简称: OCP
开闭原则是最基础的一个原则, 可以说开闭原则是我们最终需要达到的目的。 开闭原则描述的是: 对修改关闭,对扩展开放。
简单来说就是,在一些情况下,由于需求变更,导致我们的逻辑需要修改的时候,尽量不要修改原来的逻辑,而是通过增加一个新的类来实现新的逻辑需求。这也是为了减少对原有逻辑的一系列关联逻辑的影响。比如原有逻辑的单元测试程序也不会因为我们新增的实现而被改变等等。