##单一职责模式:

就一个类而言,应该仅有一个引起它变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力,当变化发生时,设计会遭受意想不到的破坏。事实上,我们完全可以找出来进行分类,分离。软件设计真正要做的许多内容,就是发现职责相互分离。其实要去判断是否应该分离出类来,那就是如果你能够想到多于一个的动机去改变一个类,那么这个类具有多于一个的职责,应该考虑职责分离。
问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
遵循单一职责原则,分布建立两个类T1、T2,使T1完成P1,T2完成P2,这样修改T1时,不会使职责P2发生故障。

##开放-封闭原则:

开闭原则是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。无论模块多么封闭,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对那种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离这些变化。面对需求,对程序的改动是通过增加新代码来实现的,而不是更改现有的代码,这就是开闭原则的精神所在。

##依赖倒转原则:

就是说抽象不应该依赖细节,细节应该依赖抽象。主要就是要针对接口编程,而不是针对细节编程。
问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成,这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。
解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。
依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构以细节为基础搭建起来的架构要稳定的多。核心思想是面向接口编程。

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

##里氏替换原则:

子类型必须能够替换掉他的父类型。只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。正是由于子类型可替换性才使得父类类型模块在无需修改的情况下就可以扩展,才使得开放-封闭原则成为了可能。
问题由来:有一功能P1,由类A完成。现在需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。
里氏替换比较通用的做法是:原来父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系代替。
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。

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

##迪米特原则:

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某个方法的话,可以通过第三者转发这个调用。迪米特原则首先强调的前提是在类的结构设计上,每一个类都应当尽量降低成员的访问权限,也就是说,一个类包装好自己的private状态,不需要别的类知道的字段或行为就不要公开。迪米特原则的根本思想,是强调了类之间的松耦合。在程序设计时,类之间的耦合越弱,越利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及,也就是说,信息的隐藏促进了软件的复用。
问题由来:类与类之间关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
解决方案:尽量降低类与类之间的耦合。
迪米特法则又叫最少知道原则,就是一个类对自己依赖的类知道的越少越好。迪米特法则只与直接朋友通信,避免与非直接的类通信,通过一个“中介”来发生联系。

##接口隔离原则:

客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。问题:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小的接口,则类B和类D必须去实现他们不需要的方法。
接口隔离未实现 隔离后的实现如下图所示: 接口隔离实现 接口隔离的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。单一职责原则注重的是职责的分离,而接口隔离注重的是接口依赖的隔离。

接口隔离要注意一下几点:

  • 接口尽量小,但要有度,如果过小,会造成接口数量过多,设计复杂化
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,隐藏它不需要的类。只有专注的为一个模块提供定制服务,才能建立最小的依赖关系
  • 提高内聚,减少对外交互,使接口用最少的方法完成最多的事情