深入解析:【设计模式笔记03】:里氏代换原则和依赖倒置原则

三、 里氏代换原则 (LSP)

1. 定义
  • 核心思想: 一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。
  • 通俗解释: 在软件里面,把父类都替换成它的子类,程序的行为没有变化。通过任何基类能够出现的地方,子类一定允许出现。
  • 简单概括: 子类型必须能够替换掉它们的父类型
2. 历史渊源
  • 里氏代换原则由Barbara Liskov于1988年提出。
  • Barbara Liskov 是2008年图灵奖得主,美国第一位计算机科学女博士,麻省理工学院教授。
3. 作用与意义
  • 正是因为有了该原则,继承复用才成为了可能。
  • 只有当子类行替换掉父类,且软件的效果不受影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
  • 子类型的可替换性才使得父类型的模块在无需修改的情况下就可以扩展。例如,系统中原来使用对象,现在可以增加等动物子类,而使用动物父类型的代码模块不需要任何改变。

在这里插入图片描述

由于子类型的可替换性才使得父类型的模块在无需修改的情况下就能够扩展

在这里插入图片描述


四、 依赖倒置原则 (DIP)

1. 定义
  • 核心思想: 高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  • 另一种表述: 要针对接口编程,不要针对搭建编程。(Program to an interface, not an implementation.)
2. 模块层次理解
  • 低层模块: 不可分割的原子逻辑,例如一些基础的类或手段。
  • 高层模块: 对低层模块进行组合和调用的复杂逻辑。
  • 传统依赖关系 (违反DIP): 高层模块直接依赖(调用)低层模块。这种设计下,一旦低层模块发生变化,高层模块也必须随之修改,系统极其不稳定。

在这里插入图片描述

3. 遵循DIP的设计
  • 引入抽象层接口或抽象类)。就是: 在高层模块和低层模块之间增加一个抽象层(通常
  • 倒置依赖关系:
    • 高层模块依赖于抽象层。
    • 低层模块也依赖于(实现或继承)抽象层。
    • 这样,高层模块与低层模块之间就不再有直接的依赖关系,它们之间的依赖关系通过抽象层来“倒置”了。

在这里插入图片描述

如图展示了正确的依赖关系。高层模块依赖于中间的抽象层,而低层模块也依赖于(达成)抽象层。高层与低层之间凭借抽象层解耦。

4. 对定义的深入理解
  • “抽象不应该依赖于细节,细节应该依赖于抽象”:

    • 抽象 (接口或抽象类): 是相对稳定的,不应该直接依赖于可能经常变化的具体完成(细节)。
    • 细节 (具体实现类): 应该去实现(或继承)抽象,遵循抽象定义的规范。
    • 代码层面: 接口或抽象类不能直接 new 实例化;细节(实现类)可以直接 new 实例化。
    • 依赖抽象暗示着多种对象的可能性(多态)。
    • 依赖细节暗示着单一对象,缺乏灵活性。
  • “要针对接口编程,不要针对实现编程”:

    • 这句话是依赖倒置原则的最佳实践。
    • 在程序代码中,我们定义的变量、方法参数、返回值类型等,应尽量使用接口或抽象类,而不是具体的建立类。
    • 这样做的好处是,当我们需要更换具体实现时,只需更换new一个新实现类的部分,而调用方的代码完全不需要改动,从而实现了对开闭原则的支持。
posted on 2026-02-06 21:18  ljbguanli  阅读(0)  评论(0)    收藏  举报