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

相关推荐
明洞日记10 小时前
【设计模式手册014】解释器模式 - 语言解释的优雅实现
java·设计模式·解释器模式
ZHE|张恒10 小时前
设计模式(十六)迭代器模式 — 统一访问集合元素的方式,不暴露内部结构
设计模式·迭代器模式
未秃头的程序猿14 小时前
🚀 设计模式在复杂支付系统中的应用:策略+工厂+模板方法模式实战
后端·设计模式
雨中飘荡的记忆14 小时前
深入理解设计模式之单例模式
java·设计模式
8***293116 小时前
能懂!基于Springboot的用户增删查改(三层设计模式)
spring boot·后端·设计模式
在未来等你1 天前
AI Agent设计模式 Day 19:Feedback-Loop模式:反馈循环与自我优化
设计模式·llm·react·ai agent·plan-and-execute
兵bing1 天前
设计模式-访问者模式
设计模式·访问者模式
python零基础入门小白1 天前
【万字长文】大模型应用开发:意图路由与查询重写设计模式(从入门到精通)
java·开发语言·设计模式·语言模型·架构·大模型应用开发·大模型学习
MC丶科1 天前
Java设计模式漫画英雄宇宙-工厂模式 —Factory博士的“超级英雄制造机”!
java·设计模式·漫画
明洞日记1 天前
【设计模式手册013】命令模式 - 请求封装的优雅之道
java·设计模式·命令模式