设计模式六大原则——里氏替换原则、依赖倒置原则详解
1、里氏代换原则(Liskov Substitution Principle)
-
概念
顾名思义,该原则用于经常发生替换的地方,在Java中指的是实现抽象和实现父子类相互替换的原则,是面向对象设计的基本原则之一
-
内容
示例源代码:
Animal抽象类:
public abstract class Animal{
//抽象方法
public abstract void eat();
}
House子类:
public class Horse extends Animal{
@Override
public void eat() {
System.out.println("马吃草");
}
//因为参数与父类不同,所以也是特有方法
public void eat(String food) {
System.out.println("马吃" + food);
}
}
Bird子类源码:
public class Horse extends Animal{
//继承父类的方法
public void eat() {
System.out.println("鸟吃食");
}
//自己特有的方法
public void fly() {
System.out.println("鸟在飞");
}
}
LSPTest测试类:
public class LSPTest {
public static void main(String[] args) {
//声明基类对象
Animal animal;
//使用基类指向子类
animal = new Horse();
animal.eat();
//使用基类指向子类
animal = new Bird();
animal.eat();
//Horse horse = new Animal(); 错误
}
}
其包含了如下四种准则:
- 子类必须完全实现父类的方法
- 子类可以有自己特有的方法
- 子类的输入参数是父类输入参数的子类或者与之一致
- 子类的返回类型是父类返回类型的子类或与之一致
-
总结
继承的优点:
- 减少创建类的工作量,因为每个子类都具有父类的属性和方法;
- 提高了代码的重用性
- 提高了可扩展性,因为子类可以有自己独特的方法和属性。
当然,继承也存在缺点:
- 继承具有入侵性,降低了代码的灵活性,因为继承后,不管愿不愿意都要拥有父类的方法和属性
- 增加了耦合,一旦父类发生变动,所有子类就相当于都被发生变动了
2、依赖倒置原则(Dependence Inversion Principle)
-
概念
传统的设计方法倾向于高层次模块依赖低层次模块,抽象层次依赖具体层次。而“倒置原则”将这个错误纠正了过来,由此命名为“依赖倒置原则”。
其包含了三层含义:
- 高层次模块不应该依赖底层模块,两者都依赖其抽象类
- 抽象不依赖细节
- 细节应该依赖于抽象
在java中的表现:
- 模块间的依赖通过抽象产生,实现类之间不直接发生依赖关系,其依赖关系是通过接口或者抽象类产生
- 接口或抽象类不依赖实现类,实现类依赖于接口或抽象类
-
内容
通俗的说,依赖倒置原则就是“面向接口编程”——OOD(Object - Oriented Design)的精髓之一。
下面是图解:
不难看出,依赖倒置的本质是通过抽象(接口或抽象类)使各个类或模块的实现实现彼此独立,互不影响,实现模块间的松耦合。
-
总结
- 每个类都应具有接口或抽象类,或者同事具备抽象类和接口,这是依赖倒置的前提条件,有了抽象才可以依赖倒置
- 任何类型都不应该从具体类派生,即应该从抽象类或接口派生
- 尽量不要重写基类的方法
- 要结合里氏替换原则(继承规范)来使用