不一样的面向对象(三)
设计模式六大原则
里式替换原则(LSP)
定义:所有引用基类的地方都必须能透明地使用其子类进行替换(简单说就是:子类可以扩展基类的功能,但是不能改变基类原有的功能)
里式替换原则是继承复用的基石,只有当子类可以替换掉基类,且其它功能不受到影响,基类才算真正的能够被复用,子类可以在基类的基础上增加新的方法
里式替换原则核心就是继承,通过继承,引用基类的地方就可以使用子类的对象了
继承的优点
(1)代码共享,每个子类都拥有父类的方法和属性
(2)提高了代码的重用性
(3)子类可以在父类的基础上扩展自己特有的功能
继承的缺点
(1)继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法
(2)降低代码的灵活性。子类必须拥有父类的属性和方法
(3)增强了耦合性。当父类的常量、变量和方法被修改时,必需要考虑子类的修改
使用里式替换原则注意的点
(1)子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法
(2)子类中可以增加自己特有的方法
(3)当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松
(4)当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格
1、子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法
在上边的例子里边,子类SonClass重写了基类中的非抽象发方法notAbstractAction(),如果将参数中的基类替换成SonClass,就会导致打印的结果发生改变。这样就会导致在父类出现的地方,不能由子类完全替换,违背了“里氏替换原则”
2、子类中可以增加自己特有的方法
还是借用上边的那个例子,SonClass2类中实现了自己特有的方法mySelfAction,子类可以拥有自己特有的方法,去实现其他的业务逻辑
依赖倒置原则(DIP)
定义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象,其核心思想是:要面向接口编程,不要面向实现编程
通俗来说就是:抽象不应该依赖于细节,细节应当依赖于抽象。 换言之,要针对接口编程,而不是针对实现编程
因为细节很容易发生改变,不稳定。而抽象通常是一个规范,不经常改变
依赖倒置原则的实现方法
每个类尽量提供接口或抽象类
变量的声明类型应该尽量是接口或者是抽象类
任何类都不应该从具体类派生
使用继承的时候,要尽量遵循上边提到的里式替换原则
代码示例
上边的类,正常的功能实现了,但是,因为射手类的射击(shot)这个功能是基于具体的类百里类(Baili)实现的,这就给以后的扩展带来了麻烦。这个时候有一个新的射手蒙犽,但是根据射手类的射击方法,蒙犽没法进行射击,除非对射手类的射击方法进行修改。按理说,只要是射手属性的英雄,就应该能够进行射击
改进,射手类中的射击方法,不应该依赖具体的某一个射手英雄,而应该是射手的泛指
这样再进行扩展的话,就会相对的容易一些,耦合度没有上边那种方式大
版权声明: 本文为 InfoQ 作者【书旅】的原创文章。
原文链接:【http://xie.infoq.cn/article/4130845442927cf22d4e1ff21】。文章转载请联系作者。
评论