面向对象设计原则–里氏替换原则(LSP)和依赖倒置原则(DIP)
tags:设计模式
LSP–inheritance should ensure that any property proved about supertype objects also hold for subtype objects.
DIP–the principle states:
A. High-lever modules should not depend on low-level modules.both should depend on abstractions.
B.Abstractions should not depend upon details.Details should depend upon abstractions.
原则简介
里氏替换原则和依赖倒置原则普遍用于各类设计模式,接口代表抽象的内容,子类相对具体,而且子类更倾向于发生”变化”.设计模式是两个原则的忠实践行者,如果说所有的设计模式有什么共同特性的话,那么就都在贯彻这两个原则,务求使客户程序”依赖于抽象而非具体”.
里氏替换原则
定义
所有引用基类的地方必须能够透明的使用其子类对象.
解释
通俗来讲:子类可以扩展父类的功能呢个,但不能改变父类原有的功能呢个,是OCP的扩展.它包含以下四层含义:
1. 子类可以实现父类的抽象,但是不能覆盖父类的非抽象方法.
2. 子类中可以增加自己特有的方法.
3. 当子类的方法重载父类的方法时,方法的前置条件要比父类方法的输入更宽松.
4. 当子类的方法实现父类的抽象方法时,方法的后置条件要比父类的更严格.
依赖倒置原则
定义
高层模块不应该依赖底层模块,二者都应该依赖抽象;抽象不应该依赖细节;细节应该依赖抽象应该依赖抽象.
核心思想
面向接口编程,含有下面三点:
1. 低层模块尽量都要有抽象类或接口,或者两者都要有
2. 变量的生命类型尽量使用抽象类或者接口
3. 用继承时遵守里氏替换原则
里氏替换原则和依赖倒置原则的区别
两者定义不同,里氏替换原则是关于子类和父类的原则;依赖倒置原则是关于抽象与细节的原则.
两者应用范围不同,依赖倒置原则比里氏替换原则使用范围更广.
涉及对象关系不同,里氏替换原则中的子类具有自己的独立性;依赖倒置原则中的细节依赖于抽象.
两者所站的角度不同,其中里氏替换原则是站在模式对象一方,而依赖倒置原则是站在客户程序一方.模式对象一方将”相对多变的”子类视同它的接口看待,而客户程序一方依赖的内容不是”相对多变的”子类,而是”相对稳定的”接口.
class interface Vehicle{
void run();
}
class Bicycle implement Vehicle{}
class Train implement Vehicle{}
class Client{
void showAVehicle (Vehicle vehicle){}
}
上面的例子不长,但是可以看到两个原则协作的效果.对于客户端程序而言,为了让车辆跑两步,它依赖的不是Bicycle或者Train,而是能跑的Vehicle;同时,无论是Bicycle还是Train,因为它们满足了Vehicle接口能”跑”的要求,所以可以被替换为接口的Vehicle来操作.