面向对象设计原则
S.O.L.I.D
S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写,是敏捷开发以及自适应软件开发的基本原则的重要组成部分。
简写 | 全拼 | 中文翻译 |
---|---|---|
SRP | The Single Responsibility Principle | 单一职责原则 |
OCP | The Open Closed Principle | 开放封闭原则 |
LSP | The Liskov Substitution Principle | 里氏替换原则 |
ISP | The Interface Segregation Principle | 接口分离原则 |
DIP | The Dependency Inversion Principle | 依赖倒置原则 |
1、单一职责原则
一个类应该只有一个引起变化的原因。
如果有一个类具有两个改变的原因,那会使得该类变化的概率上升,当需要改变这个类时,你的设计中同时有两个方面将会受到影响。尽量让每一个类保持单一责任。
内聚是一个比单一职责原则更宽泛的概念,当一个模块或一个类被设计成只支持一组相关功能时,我们说它具有高内聚。
2、开放封闭原则
类应该对扩展开放,对修改关闭。
当需求有改动时,在不改变现有代码的情况下,尽量用继承或组合的方式来扩展类的功能,来应对改变的需求。
遵循开-闭原则通常会引入新的抽象层次,增加代码的复杂度。在选择需要扩展的代码部分时需要小心。为了让你的设计简单而且有弹性,我们应恰到好处的遵循开-闭原则。
观察者模式、装饰者模式就是遵循开-闭原则的好例子。
3、里氏替换原则
子类对象必须能够替换掉所有父类对象。
只要父类出现的地方子类就可以出现,且替换成子类也不会出现任何错误或者异常。(但是反过来,有子类出现的地方,父类不一定可以适用)。
里氏替换原则为继承定义了四个规范:
- 子类必须完全实现父类的方法;
- 子类可以扩展自己的属性和方法;
- 重写或者实现父类的方法时入参可以被放大;
- 重写或者实现父类的方法时返回值可以缩小。。
4、接口分离原则
不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一、宽泛用途的接口要好。
5、依赖倒置原则
要依赖抽象,不要依赖具体类。
高层组件不应该依赖于低层组件,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
其他常见原则
除了上述的经典原则,在实际开发中还有下面这些常见的设计原则。
简写 | 全拼 | 中文翻译 |
---|---|---|
LKP | Least Knowledge Principle | 最少知识原则 |
CRP | The Composite Reuse Principle | 合成复用原则 |
HP | The Hollywood Principle | 好莱坞原则 |
CCP | The Common Closure Principle | 共同封闭原则 |
SAP | The Stable Abstractions Principle | 稳定抽象原则 |
SDP | The Stable Dependencies Principle | 稳定依赖原则 |
1、最少知识原则
一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。
最少知识原则又叫迪米特法则(Law of Demeter
),这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统的一部分,会影响到其他部分。门面模式(Facade)和中介者模式(Mediator),都是迪米特法则应用的例子
2、合成复用原则
在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
合成复用原则又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
3、好莱坞原则
别调用(打电话给)我们,我们会调用(打电话给)你。
在好莱坞原则下,允许低层组件将自己挂钩到系统上,但是由高层组件决定什么时候和以什么样的形式调用低层组件。换句话说,低层不应应调用高层,只有高层去调用低层,这样可以避免“依赖腐败”。
依赖腐败:当高层组件依赖低层组件,而低层组件又依赖于高层组件,高层组件又依赖于边侧组件,而边侧组件又易拉与低层组件时,依赖腐败就发生了: 很难理解系统是如何设计的。
模板方法模式、IOC原理都体现了好莱坞原则。
4、共同封闭原则
一起修改的类,应该组合在一起(同一个包里)。如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。
5、稳定抽象原则
最稳定的包应该是最抽象的包,不稳定的包应该是具体的包,即包的抽象程度跟它的稳定性成正比。
6、稳定依赖原则
包之间的依赖关系都应该是稳定方向依赖的,包要依赖的包要比自己更具有稳定性。
参考资料
- 《
Head First
设计模式》 - 面向对象设计的SOLID原则
- (精)分包原则/包的设计原则/组件(包)设计原则
- Java设计模式:23种设计模式全面解析(超级详细)