概述
面向对象设计的原则是为了提高软件的可维护性和可复用性。最好是在保持可维护性的同时,提高可复用性。
单一职责原则
单一职责原则(Single Responsibility Principle, SRP):一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
一个类承担的职责越多,越难以被复用。一个职责的改变可能会影响到其他职责。单一职责原则是实现高内聚、低耦合的指导方针。
开闭原则
开闭原则(Open-Closed Principle, OCP):一个软件实体应该对扩展开放,对修改关闭。
一个模块增加一个功能时,不需要修改这个模块的已有代码。一般使用抽象类等方式定义抽象层,确定一致的接口,具体的不同功能由不同的实现类根据统一的接口定义。这样添加新的功能时只需要添加新的实现类。
里氏代换原则
里氏代换原则(Liskov Substitution Principle, LSP):将程序中所有 S 类型的对象使用 T 类型的对象替换,程序的行为不发生变化,则 T 类型是 S 类型的子类型。
最初原文如下:
Let \(q(x)\) be a property provable about objects x of type T. Then \(q(y)\) should be true for objects y of type S where S is a subtype of T.
程序中使用超类的地方都可以使用子类替代,一般情况下反之不然。
依赖倒转原则
依赖倒转原则(Dependence Inversion Principle, DIP):高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。另种表述是:针对接口而不是实现编程。
尽可能地针对抽象类或者接口编程,推迟对具体类的实现。类的耦合关系中,至少一方为抽象类/接口,方便扩展。比如声明参数类型时使用抽象类型或者接口。
接口隔离原则
接口隔离原则(Interface Segregation Principle, ISP):客户端不应该依赖那些它不用的接口。(这里的“接口”指的是某种类型所提供的所有方法的集合。)
尽可能地根据实际情况将较大的接口划分成多个小的接口,保证封装性。
合成复用原则
合成复用原则(Composite Reuse Principle, CRP):尽量使用组合而不是继承达到复用的目的。
继承实现复用,会破坏超类的封装性,这种复用方式是静态的,子类也没有足够的灵活性。组合实现复用是通过将一个或者多个对象作为另一个对象的一部分,此时可以使用已有对象的方法。成员对象对新对象而言不可见,耦合度低,复用在运行时动态进行,灵活性高。
迪米特法则
迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少地和其他实体发生相互作用。
用于降低耦合度。
设计模式
定义
设计模式(design pattern):一套被反复使用、多数人知道的、经过分类的、代码设计经验的总结。目标是提高代码可重用性、可理解性、可靠性。
分类
根据目的划分:
- 创建型(creational):用于创建对象。将类的创建和使用分离。
- 结构型(structural):处理类或对象的组合。
- 行为型(behavioral):描述对类或对象的交互和职责分配。
根据范围划分:
- 类模式:处理类之间的关系,静态,在编译时确定。
- 对象模式:处理对象之间的关系,动态,在运行时变化。
参考
[1] 刘伟,设计模式,2011.