SOLID设计原则
SRP
Single Reposibility Principle 单一职责原则
A class should have one,and only one,reason to change.
- 就一个类而言,有且仅有一个引起它变化的原因。
- 每个类都必须要有一个唯一的明确的职责,只做一件事,并且把这件事做好。
- 仅当某种情况发生时(通常与这个类的职责直接相关)才需要修改这个类的代码。
- 类名和方法名应该与其所承担的职责相符。
示例
分离关注点,让其彼此独立。
OCP
Open Closed Principle 开放-封闭原则
Software entities(classes,modules,functions,etc) must be open for extension but closed for modification.
软件实体(类,模块,函数方法等)应该对扩展开发,对修改封闭。
- 一个软件当需要扩展其功能时不要修改原来的代码,而应该派生出新类。
- 仅当源代码有Bug时,才对原始程序进行修改。
- 为了在修改现有代码时不引入新的Bug。
示例
新建一个MyClass2类用以完全地替换掉MyClass类,如下所示:
LSP
Liskov Substitution Principle Liskov替换原则
Subtypes must be substituable for their base types.
子类型必须能够替换掉他们的基类型。
- 当从一个类派生出子类时,所有使用其基类的代码,在接收一个子类对象时都应该能正常工作,而不会出现错误或崩溃。
- 在具体实现上,要求应该针对接口或抽象基类进行编程,充分利用面向对象的多态特性,让实现同一接口或抽象基类的子对象可以互相取代而不影响到程序的其它部分。
- 基于封装与抽象出来的接口与抽象基类来开发上层应用具有稳定性。
示例:反例
ISP
Interface Segregation Principle 接口隔离原则
No client should be forced to depend on methods it does not use.
不应该强迫一个软件组件依赖于它们不用的方法。
要避免创建一个全能接口,而应该将其定义的功能从逻辑上进行分组,将切分为多个小的接口。
各个类可以依据实际情况选择实现不同的接口,而在不同的场景下,实现多个接口的对象又可以向外界展示出不同的特性。
示例
对于一个仅提供查询功能的类来说Save()
、Update()
等方法是毫无意义的。
仅实现查询接口的Repository类,如下所示:
DIP
Dependency Inversion Principle 依赖倒置原则
- High-level modules should not depend on low-level modules.Both should depend on abstractions.
- 高层模块不应该依赖于底层模块,两者都应该依赖于抽象。
- Abstractions should not depend upon details.Details should depend upon abstractions.
- 抽象不应该依赖于细节,细节应该依赖于抽象。
示例:
一个类不要依赖于具体的(concrete)类,而应该依赖于抽象的(abstract)类或者接口。
类本身不直接实例化它所依赖的类的对象,而是由外界动态地将其注入(inject)。