面向对象的常用设计原则
世上唯一不变的是变化。
相对于其他实物,软件从写下第一行代码开始就不断反复变化。为了应对各种变化,需要一些通用的设计原则和模式来指导日常开发。
面向对象诞生至今早已超过半个世纪,大量前辈们早就探索和总结出了一些列设计原则和设计模式。学好面向对象开发好比学好一门武功,设计原则是内功心法,设计模式是招式套路。心法和套路相辅相成,都是不可或缺的一环。
面向对象有七个设计原则:
- 开放封闭原则
- 里氏替换原则
- 依赖倒置原则
- 接口隔离原则
- 迪米特法则(最少知道原则)
- 单一职责原则
- 合成复用原则
下面分别简单描述一下。
开放封闭原则 OCP
这个原则是所有面向对象原则的核心。
任何一个软件实体(小到一个类、大到一个系统)都要对扩展开放,对修改封闭。换句话说,要在尽量不修改原有代码的基础上,对功能进行扩充。
一般实践过程中,常常通过接口、抽象类定义抽象层,然后通过实现类进行功能扩展。每次增加新功能只需要增加一个实现类即可。
里氏替换原则 LSP
所有引用基类的地方必须能透明地使用其派生类的对象。说人话,就是所有父类引用都可以换成子类的引用。
违反里氏替换原则的一个小例子:
1 | if (obj typeof SubClass1) { |
依赖倒置原则 DIP
这个原则有两层含义:
- 高层模块不应依赖于低层模块,二者都应依赖于抽象。
- 抽象不应依赖于细节,细节应依赖于抽象
- 针对接口编程,不要针对实现编程
我们在编码中,应该尽量依赖于抽象类和接口,而不是实现类。
接口隔离原则 ISP
不能强迫用户去依赖他们不使用的接口。
换句话说,接口里包含的方法定义应尽可能少! 大接口要拆分成小接口。
迪米特法则(最少知道原则) Law of Demeter ,LoD
只与你直接的朋友们通信,不要跟“陌生人”说话。
一个实体应尽可能少地与其他实体发生相互作用,使系统各模块相互独立。
单一职责原则 SIP
这个原则是主要针对类来说的,让一个类只专注于一个职责。 如果有多个职责怎么办,通过其他原则拆分、重构它!
所谓类的职责,是指引起该类变化的一个原因。
合成复用原则 Composite/Aggregate Reuse Principle ,CARP
多使用组合/聚合,少使用类继承。