【设计模式】六大原则之依赖倒置原则(Dependency Inversion Principle,‌DIP)

设计模式是对相关问题提出的解决方案。

一般而言,一个模式有四个基本要素:

  1. 模式名称 (pattern name) 一个助记名,它用一两个词语来描述模式问题、解决方案和效果。
  2. 问题(problem)描述了应该在何时使用模式,解释了问题存在的前因后果。
  3. 解决方案(solution)描述了设计的组成成分,它们之间的相互关系以及各自的职责和协作方式。
  4. 效果(consequence)描述了模式应用的效果以及使用模式应权衡的问题。

定义

依赖倒置原则Dependency Inversion Principle,‌DIP)是编程开发中的一个重要原则,具体指抽象不应该依赖于具体类,具体类应当依赖于抽象

换言之,要针对接口编程,而不是针对实现编程,旨在降低模块间的耦合度,提高系统的可维护性和稳定性。

核心思想

DIP的核心思想是:高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。这意味着在编程时,我们应该针对抽象进行编程,而不是针对具体的实现进行编程。这样可以降低客户与实现模块间的耦合,提高系统的稳定性和可重用性。‌

要求

依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

优点

采用依赖倒置原则有以下优点:

  • 减少类间的耦合性:通过依赖抽象而不是具体实现,可以降低模块之间的耦合度,使得系统更加灵活和可扩展。‌
  • 提高系统的稳定性:通过依赖抽象,可以减少因低层模块变更对高层模块的影响,从而提高系统的稳定性。
  • 提高代码的可读性和可维护性:降低模块间的直接依赖关系,使得代码更加清晰和易于维护。
    在实际应用中,DIP可以通过以下方式实现:

高层模块和低层模块都依赖于抽象:通过定义接口或抽象类,高层模块和低层模块都依赖于这些抽象,而不是直接依赖于对方。这样可以降低模块间的耦合度,提高系统的可维护性和可扩展性。‌

使用依赖注入:依赖注入是一种具体实现方法,通过将依赖关系交给外部进行注入,可以进一步降低模块间的耦合度,使得系统更加灵活和可扩展。‌

简单案例

  1. 定义抽象接口
    首先定义一个抽象接口或基类,这个接口或基类定义了一组方法,这些方法是所有具体实现都需要遵循的契约。
javascript 复制代码
// 抽象接口
class MessageSender {
  send(message) {
    throw new Error('Method "send" must be implemented.');
  }
}
  1. 创建具体实现
    然后创建具体的类来实现上述抽象接口。
javascript 复制代码
// 具体实现
class EmailSender extends MessageSender {
  send(message) {
    console.log(`Sending email: ${message}`);
  }
}

class SmsSender extends MessageSender {
  send(message) {
    console.log(`Sending SMS: ${message}`);
  }
}
  1. 使用依赖注入
    接下来,在需要发送消息的业务逻辑中,我们不直接创建EmailSender或SmsSender实例,而是通过构造函数或setter方法注入这些依赖。
javascript 复制代码
class NotificationService {
  constructor(sender) {
    this.sender = sender;
  }

  notify(message) {
    this.sender.send(message);
  }
}
  1. 使用示例
    现在我们可以根据不同的需求来注入不同的消息发送器。
javascript 复制代码
const emailSender = new EmailSender();
const smsSender = new SmsSender();

const notificationService = new NotificationService(emailSender);

notificationService.notify('Welcome to our service!'); // 输出: Sending email: Welcome to our service!

// 更换发送方式
notificationService.sender = smsSender;

notificationService.notify('Welcome to our service!'); // 输出: Sending SMS: Welcome to our service!

总结:依赖倒置原则

  1. 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
  2. 抽象不应该依赖于具体,具体应该依赖于抽象。

具体使用案例 https://segmentfault.com/a/1190000012929864

相关推荐
晨米酱33 分钟前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机6 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机7 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤7 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴1 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤1 天前
工厂模式
设计模式