1.单一职责
定义:
一个类应该有且只有一个变化的原因。
通俗点说就是:一个方法、接口或类尽量只做一件事情。
注意:
- 单一职责最难划分的是职责。
- 单一职责原则提出标准:用职责和变化原因来衡量接口或类设计的是否优良,但是职责和变化原因都是不可度量的,因项目、环境而异。
- 接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
2.里氏替换
定义:
所有引用基类的地方必须能透明的使用其子类的对象。
通俗点说就是:只要父类能出现的地方,子类就可以出现。使用者不需要关心是父类还是子类。但是反过来就不行了,子类出现的地方,父类未必可以适应。
注意:
如果采用里氏替换原则,那么尽量避免子类的“个性”,一个子类有个性,这个子类和父类之间的关系就很难调和了,把子类当做父类使用,子类的个性“被抹杀”;把子类单独作为一个业务来使用,则会让代码间的耦合关系变得扑朔迷离,缺乏类替换的标准。
3.依赖倒置
定义:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
这就是我们常说的 面向接口编程
。
依赖倒置原则的优点在小型项目中很难体现出来,例如小于10个人月的项目,使用简单的SSH架构,基本上不费太大力气就可以完成,是否采用依赖倒置原则影响不大。但是,在一个大中型项目中,采用依赖倒置原则可以带来非常多的优点,特别是规避一些非技术因素引起的问题。项目越大,需求变化的概率也越大,通过采用依赖倒置原则设计的接口或抽象类对实现类进行约束,可以减少需求变化引起的工作量剧增的情况。人员的变动在大中型项目中也是时常存在的,如果设计优良、代码结构清晰,人员变化对项目的影响基本为零。大中型项目的维护周期一般都很长,采用依赖倒置原则可以让维护人员轻松地扩展和维护。
注意:
- 在代码中传递参数或关联关系时,尽量引用高层的抽象层类,即使用接口和抽象类进行变量声明、参数类型声明、
方法返回类型声明以及数据类型的转换; - 当一个对象和其他对象有依赖关系时,可以利用依赖注入的方法将类之间进行解耦,
主要有:
(1) 构造注入、
(2) Set方法注入
(3) 和接口注入; - 开闭是原则,里氏是基础,依赖倒置是手段;
- 低层模块尽量都要有抽象类或接口,或者两者都有;
- 变量的声明类型尽量是抽象类或接口;
- 使用继承时遵循里氏替换原则。
4.接口隔离
定义:
建立单一接口,不要建立臃肿庞大的接口。再通俗的一点讲: 接口尽量细化,同时接口中的方法尽量的少。
接口隔离原则与单一职责的定义的规则是不相同的,单一职责要求的是类和接口职责单一,注 重的是职责,没有要求接口的方法减少,例如一个职责可能包含 10 个方法,这 10 个方法都放在一个接口 中,并且提供给多个模块访问,各个模块按照规定的权限来访问,在系统外通过文档约束不使用的方法不 要访问,按照单一职责原则是允许的,按照接口隔离原则是不允许的,因为它要求“尽量使用多个专门的 接口”,专门的接口指什么?就是指提供给多个模块的接口,提供给几个模块就应该有几个接口,而不是建 立一个庞大的臃肿的接口,所有的模块可以来访问。
注意:
在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。
5.迪米特法则
定义:
一个对象应该对其他对象保持最少了解, 通俗的讲就是一个类对自己依赖的类知道的越少越好,也就是对于被依赖的类,向外公开的方法应该尽可能的少。
注意:
迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。其要求的结果就是产生了大量的中转或跳转类,导致系统的复杂性提高,同时也为维护带来了难度。在采用迪米特法则时需要反复权衡,既做到让结构清晰,又做到高内聚低耦合。
6.开闭原则
定义:
一个软件实体。如类/模块/函都应该对扩展开放,对修改关闭。
注意:
开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统,开闭原则只定义了对修改关闭,对扩展开放。其实只要遵循前面5中设计模式,设计出来的软件就是符合开闭原则的。
总结
6个原则:
1.开闭原则是总纲。
2.接口隔离原则告诉我们如何设计接口。
3.依赖倒置原则告诉我们在软件架构设计时增加一层抽象层。(在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。)
4.有了抽象层,就会出现继承关系,里氏替换原则是规范继承体系的。
5.迪米特法则是规范类间的依赖的。
6.单一职责原则主要是为了实现复用。
其实23种设计模式,主要的目的是:增加程序的可维护性。可维护性是什么:程序的可读性,程序的是否方便扩展和修改,怎么实现呢?尽量复用,尽量解耦,即高内聚,低耦合。怎么实现复用和解耦,封装可以实现内聚,增加一层可以实现解耦。