- S Single Responsibility Principle
- O Open Closed Principle
- L Liskov Substitution Principle
- I Interface Segregation Principle
- D Dependency Inversion Principle
写在前面
一切的设计原则,设计模式都是为了让程序 “高可扩展,高内聚,低耦合”。
单一职责原则
一个类或者模块只负责完成一个职责(或者功能)
- 类中的代码行数、函数或属性过多,会影响代码的可读性和可维护性,我们就需要考虑对类进行拆分;
- 类依赖的其他类过多,或者依赖类的其他类过多,不符合高内聚、低耦合的设计思想,我们就需要考虑对类进行拆分;
- 私有方法过多,我们就要考虑能否将私有方法独立到新的类中,设置为 public 方法,供更多的类使用,从而提高代码的复用性;
- 比较难给类起一个合适名字,很难用一个业务名词概括,或者只能用一些笼统的 Manager、Context 之类的词语来命名,这就说明类的职责定义得可能不够清晰;
- 类中大量的方法都是集中操作类中的某几个属性,比如,在 UserInfo 例子中,如果一半的方法都是在操作 address 信息,那就可以考虑将这几个属性和对应的方法拆分出来。
开闭原则
对拓展开放,对修改封闭
- 此条原则并不是让我们完全不动之前的代码,而是一个建议:建议我们设计的时候要注意让我们的程序易于拓展。当有新的业务逻辑时,能很方便的添加。
- 所有的设计原则,设计模式都是为了让我们的系统更易于维护,更易于拓展
里式替换替换原则
对于父类对象出现在系统中的位置,子类对象能无缝替换
- 子类在设计的时候,要遵守父类的行为约定(或者叫协议)。父类定义了函数的行为约定,那子类可以改变函数的内部实现逻辑,但不能改变函数原有的行为约定。这里的行为约定包括:函数声明要实现的功能;对输入、输出、异常的约定;甚至包括注释中所罗列的任何特殊说明。实际上,定义中父类和子类之间的关系,也可以替换成接口和实现类之间的关系。
- 我的理解是减少代码的不确定性,当子类重写了父类方法。子类对象当然是多态调用子类 实现。但当异常出现,逻辑按子类运行不通,至少要运行父类逻辑。
接口隔离原则
客户端不应该被强迫依赖它不需要的接口。其中的“客户端”,可以理解为接口的调用者或者使用者
- 不同于单一职责原则针对的是模块、类、接口。接口隔离原则只针对接口。实现接口的类实现方法的时候不应该实现和自己无关的方法。换句话说,在顶层设计接口的时候,一定要保证接口的颗粒度。如果在后续编码中发现接口过于臃肿,则要拆分成更小的更适用的接口。
依赖反转原则
高层模块不依赖低层模块,它们共同依赖同一个抽象。抽象不要依赖具体实现细节,具体实现细节依赖抽象。
- 明明是高层次模块要使用低层次模块,对低层次模块有依赖性。现在反而低层次模块需要根据高层次模块来设计,出现了「倒置」的显现。
- 好处是修改、添加业务逻辑的时候不用修改与之相关的调用逻辑,不用程序员显示的加入流程,而是通过聚合注入的方式,形参为接口,实参为我们想用调用的子对象。