SOLID 是 面向对象编程 和 面试对象设计 的五个基本原则,应用这五个原则能创建一个易于维护和扩展的软件系统。
首字母 - 简写(全称) | 指代 | 概念 |
---|---|---|
S-SRP(Single Responsibility Principle) | 单一功能原则 | 对象应该仅具有一种单一功能 |
O-OCP(Opened Closed Principle) | 开闭原则 | 软件应该是对于扩展开放的,但对于修改封闭的 |
L-LSP(Liskov Substitution Principle) | 里氏替换原则 | 程序中的对象应该是可以在不改变程序正确性的前提下被他的子类所替换 |
I-ISP(Interface Segregation Principle) | 接口隔离原则 | 多个特定客户端接口要好于一个宽泛用途的接口 |
D-DIP(Dependency Inversion Principle) | 依赖反转原则 | 一个方法应该遵从「依赖于抽象而不是一个实例」 |
总结
SRP | 单一职责原则 | 一个类有且只有一个更改的原因 |
---|---|---|
OCP | 开闭原则 | 能够不更改类而扩展类的行为 |
LSP | 里氏替换原则 | 派生类可以替换基类使用 |
ISP | 接口隔离原则 | 使用客户端特定的细粒度接口 |
DIP | 依赖反转原则 | 依赖抽象而不是具体实现 |
定义
- 单一职责(SRP)如何正确的划分职责,类的职责单一提高代码复用性,降低耦合性
- 接口隔离(ISP)合理划分接口功能,保证接口的专一性,纯洁性,减少依赖关系
- 里氏替换(LSP)合理利用类的继承体系,保证正确的继承关系不被破坏
- 依赖倒置(DIP)抽象接口编程由于抽象具体实现
- 开放封闭(OCP)面向对象编程终极目标所达到的结果,类/模块/系统的功能行为可扩展,内部更改性是封闭的
单一职责原则
定义与特性
- 仅有一个引起类变化的原因,即一个类只承担一项职责
- 避免相同的职责分散到不同的类中,造成功能重复
优势:
- 减少类之间的耦合:当需求变化时,只修改一个类,从而隔离了变化带来类对其他职责的影响
- 提高类的复用性:按需引用,一个类负责一个职责,需求的变动只需要修改对应的类或增加某一职责
- 降低类的复杂度:职责单一,功能分散开降低一个类多个职责类的复杂度
在实际代码开发中的应用:工厂模式、命令模式、代理模式等。
接口隔离原则
定义,特性
- 客户端不应该依赖他们不需要的方法/功能
- 一个类对一个类的依赖应该建立在最小的接口上
- 接口的实现类应该只呈现为单一职责原则
优势:
- 将胖接口分离,每一组接口提供特定功能服务于特定一组的客户端程序
- 对一组接口的更改不会/较小的影响到其他的接口/客户端程序,保证接口的纯洁性
单一职责和接口隔离比较
- 都是解决软件设计中依赖关系原则
- SRP 注重职责的划分,主要约束类,其实是接口和方法,是程序中的细节和实现。ISP 注重接口的隔离,约束的是接口,从更宏观的角度对接口的抽象设计
开放封闭原则
定义,特性
- 一个模块在扩展行为方面应该是开放的而在更改性方面应该是封闭的
优势:
- 模块的行为是可扩展的,可以方便的对现有模块的行为/功能进行扩展
- 对于模块行为的扩展不会/较小的影响现有系统/模块
总结
OCP核心思想就是抽象接口编程,抽象相对稳定。让类依赖与固定的抽象,通过面向对象的继承和多态让类继承抽象,复写其方法或固有行为,是想新的扩展方法/功能,实现扩展。
里氏替换原则
定义,特性
- 子类必须能够替换掉他们的基类型:任何出现基类的地方都可以替换成子类并且客户端程序不会改变基类行为或者出现异常和错误,反之不行。
- 客户端程序只应该使用子类的抽象父类,这样可以实现动态绑定(php多态)
总结
LSP是OCP得以应用的最主要的原则之一,正是因为子类性的可替换行是的基类类型在无需修改的情况下扩展功能。
依赖倒置原则
定义,特性
- 高层模块不应该依赖与底层模块,二者都应该依赖于抽象
- 抽象不应该依赖与细节,细节应该依赖于抽象
总结
DIP原则就是每个高层次模块定义一个它所需服务的接口声明,低层次模块实现这个接口。每个高层次类通过该抽象接口使用服务。