设计原则

设计原则则是设计模式所遵循的规则,设计模式就是实现了这些原则,从而达到了代码复用、增加可维护性的目的。

单一职责原则

一个类,只有一个引起它变化的原因。应该只有一个职责。

  • 问题由来:类T负责两个不同的职责P1和P2。由于职责P1需要发生改变而需要修改T类,就有可能导致原来运行正常的职责P2功能发生故障。

  • 解决方法:遵循单一职责原则。分别建立新的类来对应相应的职责;这样就能避免修改类时影响到其他的职责;

每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。

例:要实现逻辑和接口的分离。

优点:类的复杂性将会降低,可读性将会大大提高,维护性也会提高。

开放封闭原则

软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

  • 对扩展开放

    • 意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
  • 对修改封闭

    • 意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
  • 封装变化,是实现开放封闭原则的重要手段,对于经常发生变化的状态一般将其封装为一个抽象。

  • 拒绝滥用抽象,只将经常变化的部分进行抽象,这种经验可以从设计模式的学习与应用中获得。

里氏替换原则

子类可以扩展父类的功能,但不能改变父类原有的功能

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

最少知识原则

最少知识原则又叫迪米特法则。核心思想是:低耦合、高内聚

一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

接口隔离原则

定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上,否则将会造成接口污染;类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现它们不需要的方法;

原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少;就是说,我们要为每个类建立专用的接口,而不要试图去建立一个庞大的接口供所有依赖它的类去调用;

  • 接口尽量小,但是要有限度。对接口进行细化可以提高进程设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

依赖倒置原则

核心思想是面向接口编程

问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来完成;这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原则操作;假如修改类A,会给进程带来不必要的风险。

解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I来间接与类B和类C发生联系,则会降低修改类A的几率;

  • 低层模块尽量都要有抽象类或接口,或者两者都有。
  • 变量的声明类型尽量是抽象类或接口。
  • 使用继承时遵循里氏替换原则。