【设计模式】六大原则之依赖倒置原则(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

相关推荐
我码玄黄11 小时前
JS 的行为设计模式:策略、观察者与命令模式
javascript·设计模式·命令模式
会敲代码的小张12 小时前
设计模式-观察者模式
java·开发语言·后端·观察者模式·设计模式·代理模式
宗浩多捞12 小时前
C++设计模式(更新中)
开发语言·c++·设计模式
秦哈哈13 小时前
【软件设计】常用设计模式--观察者模式
观察者模式·设计模式
蔚一20 小时前
Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)
java·后端·设计模式·intellij-idea·接口隔离原则
严文文-Chris21 小时前
【设计模式-外观】
android·java·设计模式
yyqzjw1 天前
【设计模式】观察者模式
算法·观察者模式·设计模式
Tech_gis1 天前
C++ 常用设计模式
设计模式
java_heartLake1 天前
设计模式之抽象工厂模式
设计模式·抽象工厂模式
codefly-xtl1 天前
单例模式详解
java·单例模式·设计模式