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

相关推荐
编程、小哥哥13 分钟前
设计模式之组合模式(营销差异化人群发券,决策树引擎搭建场景)
决策树·设计模式·组合模式
hxj..1 小时前
【设计模式】外观模式
java·设计模式·外观模式
吾与谁归in1 小时前
【C#设计模式(10)——装饰器模式(Decorator Pattern)】
设计模式·c#·装饰器模式
无敌岩雀3 小时前
C++设计模式行为模式———命令模式
c++·设计模式·命令模式
In_life 在生活12 小时前
设计模式(四)装饰器模式与命令模式
设计模式
瞎姬霸爱.13 小时前
设计模式-七个基本原则之一-接口隔离原则 + SpringBoot案例
设计模式·接口隔离原则
鬣主任14 小时前
Spring设计模式
java·spring boot·设计模式
程序员小海绵【vincewm】15 小时前
【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
设计模式·tomcat·源码·外观模式·1024程序员节·门面模式
丶白泽15 小时前
重修设计模式-行为型-命令模式
设计模式·命令模式
gjh120819 小时前
设计模式:工厂方法模式和策略模式
设计模式·工厂方法模式·策略模式