一.“单一职责”原则(Single Respnsibility Principle) SRP
单一职责原则的定义是:应该有且仅有一个原因引起类的变更。
单一职责原则的好处:
1、类的复杂性降低,实现什么职责都有清晰的定义;
2、可读性提高,复杂性降低,那当然可读性就提高了;
3、可维护性提高,可读性提高,那当然更容易维护了;
4、变更引起的风险降低,变更是必不可少的,如果一个接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。
单一职责原则适用于接口,类,也同样适用于方法,什么意思呢?一个方法尽可能去做一件事情。比如一个方法“修改用户密码”,不要把这个方法放到“修改用户信息”方法中,这个方法的颗粒很粗。
对于单一职责,给予的建议是:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
注意:单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。
二.“里氏替换”原则(Liskvo Substitution Principle) LSP
里氏替换原则的定义是:所有引用基类的地方必须能透明地使用到其子类的对象。
里氏替换原则的好处:
1、代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
2、提高代码的重用性;
3、子类可以形似父类,但又异于父类,“龙生龙,凤生凤,老鼠生来会打洞”是说子拥有父的“种”,“世界上没有两片完全相同的叶子”是指明子和父的不同;
4、提高代码的可扩展性,实现父类的方法就可以“为所欲为”了,可以看到很多开源框架的扩展接口都是通过继承父类来完成的;
5、提高产品或项目的开放性;
当然继承也是有缺点的,缺点如下:
1、继承是浸入性的。只要继承,就必须拥有父类的所有属性和方法;
2、降低代码的灵活性。子类必须拥有父类的所有属性和方法,让子类自由的世界中多了些约束;
3、增强了耦合性。当父类的常量、变量和方法被修改时,必须要考虑子类的修改,而且是在缺乏规范的环境下,这种修改可能带来非常糟糕的结果----大片代码需要重构。
注意:如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组 合等关系代替继承。里氏替换原则可以正着用,但是不能反着用,在子类出现的地方,父类未必就可以胜任。
里氏替换原则为良好的继承定义了一个规范:
1、子类必须完全实现父类的方法;
2、子类可以有自己的个性;
3、覆盖或实现父类的方法时输入参数可以被放大;(子类中方法的前置条件(即传入参数类型)必须与超类中被覆写的方法的前置条件相同或更宽松)。
4、覆写或实现父类的方法时输出结果可以被缩小;
三.“依赖倒置”原则(Dependence Inversion Principle) DIP
依赖倒置原则在java语言中的表现是:
1、模块间的依赖通过抽象发生,实现类之间不能发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
2、接口或抽象类不依赖于实现类;
3、实现类依赖接口或抽象类;
更加精简的定义就是“面向接口编程”------OOD的精髓之一。
依赖倒置原则的好处:
依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。
注意:设计是否具备稳定性,只要适当地“松松土”,观察“设计的蓝图”是否还可以茁壮地成长就可以得出结论,稳定性较高的设计,在周围环境频繁发生变化的时候,依然可以做到“我自岿然不动”。