设计模式之(单一职责原则、里氏替换原则)

1,092 阅读3分钟
2019.07.08:前行的路本就艰难,跪在坚持。
一、单一职责原则
单一职责原则:英文名称是Single Responsiblity Principle,简称是SRP。定义:应该有且仅有一个原因引起类的变更。
不同的类应该是有不能的职责,一个类负责一个职责。
好处:
  1. 类的复杂性降低,实现什么职责都有清晰明确的定义;
  2. 可读性提高,复杂性降低,那当然可读性提高了;
  3. 可维护性提高,可读性提高,那当然更容易维护了;
  4. 变更引起的风险降低。
简单的总结就是可读性搞,可扩展性也高。
二、里氏替换原则
里氏替换原则:英文名称是Liskov Substitution Principle,简称LSP。两种定义:
  • 第一种定义,也是最正宗的定义:If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T ,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.(如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。)
  • 第二种定义:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.(所有引用基类的地方必须能透明地使用其子类的对象。)
通俗点讲,只要父类出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就能适应。
里氏替换原则为良好的继承定义了一个规范,一句简单的定义包含了4层含义:
  1. 子类必须完全实现父类的方法;
  2. 在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则;如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。子类可以有自己的个性;
  3. 覆盖或实现父类的方法时输入参数可以被放大;如果父类的输入参数类型大于子类的输入参数类型,会出现父类存在的地方,子类未必会存在,因为一旦把子类作为参数传入,调用者很可能进入子类的方法范畴;子类中方法的前置条件必须与超类中被覆写的方法的前置条件相同或者更宽松。
  4. 覆写或实现父类的方法时输出结果可以被缩小。父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么里氏替换原则就要求S必须小于等于T,也就是说,要么S和T是同一个类型,要么S是T的子类。
总结:子类型必须能够替换掉它们的父类型,子类型可以去扩展自己的方法,但不能改变父类原有的功能。
好处:
  1. 代码共享,减少创建类的工作量
  2. 提高代码的重用性
  3. 提高代码的可扩展性
  4. 提高产品代码的开放性
缺点:
  1. 继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法。
  2. 降低了代码的灵活性。因为继承时,父类会对子类有一种约束。
  3. 增强了耦合性。当需要对父类的代码进行修改时,必须考虑到对子类产生的影响。有时修改了一点点代码都有可能需要对打断程序进行重构。