开放封闭原则(Open - ClosedPrinciple ,OCP)
定义:一个模块、类、函数应当是对修改关闭,扩展开放。即软件实体应尽量在不修改原有代码的情况下进行扩展
修改原有的代码可能会导致原本正常的功能出现问题。
因此,当需求有变化时,最好是通过扩展来实现,增加新的方法满足需求,而不是去修改原有代码。
为什么使用开闭原则:
第一:开闭原则非常有名,只要是面向对象编程,在开发时都会强调开闭原则
第二:开闭原则是最基础的设计原则,其它的五个设计原则都是开闭原则的具体形态,也就是说其它的五个设计原则是指导设计的工具和方法,而开闭原则才是其精神领袖。即开闭原则是抽象类,而其它的五个原则是具体的实现类。
2.单一职责原则(Single Responsibility Principle, SRP)
定义:每个类应该实现单一的职责,否则应该把类拆分。
一个类职责过大的话,首先引起的问题就是这个类比较大,显得过于臃肿,同时其复用性是比较差的。
其次就是如果修改某个职责,有可能引起另一个职责发生错误。这是我们极力所避免的,因此设计一个类时我们应当去遵循单一职责原则。
3.里氏代换原则( Liskov Substitution Principle ,LSP )
定义:使用父类的地方能够使用子类来替换;子类的所有方法必须在父类中声明。
使用子类对象去替换父类对象,程序将不会产生错误
因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
需要注意的是:
子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏代换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义,如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中使用该方法。
父类应当被尽量设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现
里氏替换原则的通俗理解就是:子类可以扩展父类的功能,但是不能改变父类原有的功能。也就是说,在子类继承父类的时候,除了添加新的方法完成新增功能之外,尽量不要重写父类的方法。
如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。
如果程序违背了里氏替换原则,则继承的对象在基类出现的地方会出现运行错误。这时其修正方法是:取消原来的继承关系,重新设计他们之间的关系。
任何基类可以出现的地方,子类一定可以出现。里氏替换原则是继承复用的基石,只有当衍生类可以替换基类,软件单位的功能不受到影响时,即基类随便怎么改动子类都不受此影响,那么基类才能真正被复用
子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。
子类中可以增加自己特有的方法。
4.依赖倒置原则( Dependence Inversion Principle ,DIP )
定义:这是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。
高层模块不应该依赖低层模块,应该去依赖抽象。
抽象不应该依赖细节
细节应该依赖抽象
其主要目的为了解耦
每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块(一般是接口,抽象类),原子逻辑的组装就是高层模块。抽象就是指接口或抽象类,两者都不能被直接实例化。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,可以被直接实例化。
模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点,就能在项目中满足这个规则。
(1)每个类尽量提供接口或抽象类,或者两者都具备。
(2)变量的声明类型尽量是接口或者是抽象类。
(3)任何类都不应该从具体类派生。
(4)使用继承时尽量遵循里氏替换原则
5.接口隔离法则(Interface Segregation Principle,ISL)
定义:一个类对另一个类的依赖应该建立在最小的接口上。
一个类不应该依赖他不需要的接口。每个接口不存在子类用不到却必须实现的方法,否则要将接口拆分。
接口的粒度要尽可能小,如果一个接口的方法过多,可以拆成多个接口。
接口隔离原则的实现方法
在具体应用接口隔离原则时,应该根据以下几个规则来衡量。
(1)接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
(2)为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
(3)了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑。
(4)提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
6.迪米特法则(Law of Demeter, LoD)
定义:又叫作最少知识原则;一个类尽量不要与其他类发生关系
一个类对其他类知道的越少,耦合越小。
当修改一个类时,其他类的影响就越小,发生错误的可能性就越小。
总结
单一职责原则告诉我们实现类要职责单一
里氏替换原则告诉我们不要破坏继承体系
依赖倒置原则告诉我们要面向接口编程
接口隔离原则告诉我们在设计接口的时候要精简单一
迪米特原则告诉我们要降低耦合