天天看点

面向对象程序设计六大原则

面向对象程序设计中,需要遵守的原则可总结为6个,这就是大名鼎鼎的六大原则。面向对象程序设计原则也是我们用于评价一个设计模式的重要指标之一。在设计模式中,很多设计模式都遵守了这些原则。

  1. 单一职责原则(Single Responsibility Principle)
  2. 里氏替换原则(Liskov Substitution Principle)
  3. 依赖倒置原则(Dependence Inversion Principle)
  4. 接口隔离原则(Interface Segregation Principle)
  5. 迪米特法则(Law Of Demeter)
  6. 开闭原则(Open Close Principle)

单一职责原则

什么是单一职责原则

单一职责原则(Single Responsibility Principle, SRP):即一个类只负责相应领域的职责,即不要存在多于一个导致类变更的原因。(There should never be more than one reason for a class to change。)

起源

罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。

为什么要使用单一职责原则

一个类承担的职责越多,当一个职责变化时,其他职责受到影响的可能性就越大,软件出现错误的可能性就越大。

优点

  • 降低类的复杂度。一个只有一个职责的类肯定比有多个职责的类要简单。
  • 降低因职责修改带来的风险。

缺点

  • 说是缺点其实不准确。在实际操作中,想要遵循单一职责原则总是受到种种约束。要注意,原则是死的,人是活的,要根据实际情况来决定是否要遵循单一职责原则。

问题

1.有哪些设计模式遵循了单一职责原则

  • 迭代器模式。将聚合器类的遍历职责剥离出来,使聚合器类遵守“单一职责原则”。

欢迎补充。

里氏替换原则

什么是里氏替换原则(Liskov Substitution Principle,LSP)

严格定义:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

通俗定义:任何基类可以出现的地方,子类一定可以出现。

为什么要遵守里氏替换原则

LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

如何遵守里氏替换原则

在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

优点

待补充

缺点

待补充

问题

1.有哪些设计模式遵循了里氏替换原则

待补充。

依赖倒置原则

什么是依赖倒置原则(Dependency Inversion Principle, DIP)

依赖倒置原则两个要点:

  • 高层次的模块不应该依赖于低层次的模块,两者应该依赖于抽象。
  • 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

为什么要遵守依赖倒置原则

依赖倒置原则(Dependence Inversion Principle)要求程序依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程。一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,程序就不需要变化。这大大降低了调用方与实现细节的耦合度。

如何遵守依赖倒置原则

  • 变量的声明类型尽量是抽象类或接口。
  • 被引用的模块尽量都要有抽象类或接口,或者两者都有,引用它们时使用它们的抽象。

优点

待补充

缺点

待补充

问题

1.有哪些设计模式遵循了依赖倒置原则

欢迎补充。

接口隔离原则

什么是接口隔离原则(Interface Segregation Principle, ISP)

  • 客户端不应该依赖它不需要的接口。
  • 一个类对另一个类的依赖应该建立在最小的接口上。

为什么要遵守接口隔离原则

需要什么用什么,把客户端不需要用的东西放在接口里,对客户端没有好处,而且需要承担这些不需要的东西所带来的风险。

如何遵守接口隔离原则

尽量细化接口,接口中的方法尽量少。即为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

优点

待补充

缺点

待补充

问题

1.有哪些设计模式遵循了接口隔离原则

欢迎补充。

迪米特法则

什么是迪米特法则

迪米特法则(Law of Demeter,LoD),又叫作最少知道原则(Least Knowledge Principle,LKP)。就是说一个对象应当对其他对象保持最少的了解。

为什么要遵守迪米特法则

类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易。

如何遵守迪米特法则

尽量降低类与类之间的耦合。

优点

待补充

缺点

待补充

问题

1.有哪些设计模式遵循了迪米特法则

  • 外观模式。外观模式对客户端屏蔽子系统,客户端不需要了解子系统,直接访问外观类即可。
  • 责任链模式。请求发送者只负责创建责任链,不需要知道请求被哪个处理者处理,怎样处理。
  • 命令模式。请求者和接受者之间不存在直接引用,实现了解耦。
  • 中介者模式。中介者模式将各同事解耦,实现了“一个对象应当对其他对象保持最少的了解”。
  • 观察者模式。观察者和目标是抽象耦合的。目标只是维持了一个观察者的集合,而不知道任何一个观察者是属于哪个具体的类的。这样目标和观察者之间的耦合是最小的。

认知有限,欢迎补充。

开闭原则

什么是开闭原则

开闭原则(Open Closed Principle):一个软件实体应该对扩展开放,对修改关闭。

软件实体

软件实体指的是如类、模块和函数。

为什么要遵守开闭原则

需求的变动是任何一软件系统都难以避免的问题,在需求变动时,如果软件系统遵守开闭原则,那么就能不修改原有代码,而是在现有的代码的基础上进行扩展。在软件规模越来越大,寿命越来越长的今天,遵守开闭原则变得尤其重要。

如何遵守软件符合开闭原则

抽象化。

优点

待补充

缺点

待补充

问题

1.有哪些设计模式遵循了开闭原则

  • 工厂方法模式。在工厂方法模式中,当需要新增一种产品时,只需要新增一个产品类和工厂类即可,不需要修改原有代码。
  • 抽象工厂模式。增加新的具体工厂和产品族很方便,无须修改已有系统。
  • 建造者模式。指挥者类针对抽象建造者类编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便。
  • 适配器模式。可以在不修改原有代码的基础上增加新的适配器类。
  • 桥接模式。在抽象部分和实现部分两个变化维度中任意扩展一个维度,都不需要修改原有代码。
  • 组合模式。在组合模式中新增叶子构件和容器构件都很方便。
  • 装饰模式。客户端可以根据具体需要添加具体构建类和具体装饰类,并进行组合。
  • 责任链模式。想要新增一个处理者,只需要在客户端中重新建立链即可,原有系统不需要修改。
  • 命令模式。加入新的具体命令类不会影响原有系统。
  • 解释器模式。在解释器模式中,增加新的解释表达式较为方便。如果需要增加新的解释表达式,只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改。
  • 迭代器模式。由于有抽象聚合类和抽象迭代器类,添加新的聚合类和迭代器都不需要修改原有代码。
  • 中介者模式。如果需要引入新的具体同事类,只需要继承抽象同事类并实现其中的方法即可,由于具体同事类之间并无直接的引用关系,因此原有所有同事类无须进行任何修改,它们与新增同事对象之间的交互可以通过修改或者增加具体中介者类来实现。如果需要增加新的具体中介者类,只需要继承抽象中介者类(或已有的具体中介者类)并覆盖其中定义的方法即可,在新的具体中介者中可以通过不同的方式来处理对象之间的交互,也可以增加对新增同事的引用和调用。
  • 观察者模式。可以在不修改原有系统的条件下灵活的新建新的策略。
  • 模板方法模式。可以在不修改原有代码的前提下灵活的新增具体子类。
  • 部分遵守开闭原则。为什么说部分遵守呢?因为新增新的访问操作很方便,仅需要增加一个新的访问者即可在一个对象结构上定义一个新的操作。但如果需要新增元素类,要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。

欢迎补充。

继续阅读