设计原则
开闭原则
开闭原则(Open Close Principal)定义:一个软件实体如类、模块和方法应该对扩展开放,对修改关闭,以降低代码修改的风险。
核心思想:用抽象构建框架,用实现扩展细节
优点:
- 有利于构建一个稳定的系统
- 提高软件系统的可复用性及可维护性
依赖倒置原则
依赖倒置原则(Dependence Inversion Principle)定义:高层模块不应该依赖低层模块,两者都应该依赖其抽象
- 抽象不应该依赖细节,细节应该依赖抽象
- 针对接口编程,不要针对实现编程
核心思想:底层代码不改动,改动主要在应用层
优点:
- 可以减少类间的耦合度
- 提高系统稳定性
- 提高代码可读性和可维护性
- 可降低修改程序所造成的风险
单一职责原则
单一职责原则(Simple Responsibility Principle)定义:不要存在多于一个导致类变更的原因
核心思想:一个类、接口、方法尽量只负责一项职责
优点:
- 降低类的复杂度
- 提高类的可读性
- 提高系统的可维护性
- 降低变更引起的风险
接口隔离原则
接口隔离原则(Interface Segregation Principle)定义:用多个专门的接口,而不是使用单一的总接口,客户端不应该依赖它不需要的接口
符合高内聚低耦合的思想
注意:
- 一个类对应一个类的依赖应该建立在最小的接口上
- 建立单一接口,不要建立庞大臃肿的解耦
- 尽量细化接口,接口中的方法尽量少
- 注意适度原则
单一职责原则与接口隔离原则对比
平台支持多种登陆方式,包括微信、QQ、支付宝。现在把登陆方式都拆分成具体的微信登录、支付宝登录、QQ登录等单独的接口,这体现了单一职责原则;然后新的系统只支持微信登陆和支付宝登录,就只实现这两个接口,不支持的QQ登录接口就不依赖,这体现了接口隔离原则。先有单一职责原则再有接口隔离原则
迪米特法则
迪米特法则(Law Of Demeter)定义:一个对象应该对其他对象保持最少的了解,又称最少知道原则
核心:不要和陌生人说话
出现在成员变量、方法的输入、输出参数中的类称为成员朋友类
优点:降低类之间的耦合
里氏替换原则
里氏替换原则(Liskov Substitution Principle)定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。一个软件实体如果适用一个父类的话,那一定适用于其子类,所有引用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。
- 子类的参数列表比父类的参数列表更宽松
- 子类的返回值要比父类的返回值更加严格或相等
合成复用原则
合成复用原则(Composite & Aggregate Reuse Principle)定义:尽量使用对象组合(has)、聚合(contains),而不是继承(is)关系达到软件复用的目的。因为继承关系的依赖关系非常强,如果作为一个参数传入的话会更好
优点:使系统更加灵活,降低类与类之间的耦合度
使用场景:
- 聚合:电脑与U盘,合成到一起可以一起工作,分开后也能独立存在,生命周期独立的个体
- 组合:独立的物体,合到一起之后形成一个具有相同生命周期的个体。如:人体的各个部分(手、脚),缺一不可
- 继承:狗与动物,把一些特征都抽取出来放到顶层,让所有子类都具备这些特征、行为
总结
不是非要遵循所有原则,只是在开发过程中尽可能地遵循,但也要联系实际情况
| 设计原则 | 一句话归纳 | 目的 |
|---|---|---|
| 开闭原则 | 对扩展开放,对修改关闭 | 减少维护带来新的风险 |
| 依赖倒置原则 | 底层不应该依赖应用层 | 更利于代码结构的升级和扩展 |
| 单一职责原则 | 一个类只干一件事 | 便于理解,提高代码可读性 |
| 接口隔离原则 | 一个接口只干一件事 | 功能解耦,高聚合,低耦合 |
| 迪米特法则 | 不该知道的事情不要知道 | 不和陌生人说话,减少代码臃肿 |
| 里氏替换原则 | 子类重新方法功能发生改变 不应该影响父类方法的含义 | 防止继承泛滥 |
| 合成复用原则 | 尽量使用组合而非继承实现代码复用 | 降低代码耦合度 |