首页 > 后端开发 > Python教程 > 分解依赖倒置、IoC 和 DI

分解依赖倒置、IoC 和 DI

DDD
发布: 2025-01-20 16:26:09
原创
282 人浏览过

Breaking Down Dependency Inversion, IoC, and DI

探索 NestJS 的依赖注入系统引发了对依赖反转、控制反转和依赖注入的更深入研究。 这些概念虽然看似相似,但却为不同的问题提供了不同的解决方案。 此解释可作为个人复习,并希望能为其他处理这些术语的人提供有用的指南。


  1. 依赖倒置原则(DIP)

定义:高层模块不应该依赖于低层模块;两者都应该依赖于抽象。抽象不应该依赖于细节;细节应该取决于抽象。

这意味着什么:

在软件中,高层模块封装核心业务逻辑,而低层模块处理特定的实现(数据库、API 等)。 如果没有 DIP,高层模块直接依赖低层模块,造成紧密耦合,阻碍灵活性,使测试和维护复杂化,并且使替换或扩展低层细节变得困难。

DIP 颠倒了这种关系。高层和低层模块都依赖于共享抽象(接口或抽象类),而不是直接控制。


无 DIP

Python 示例

<code class="language-python">class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self):
        self.email_service = EmailService()

    def notify(self, message):
        self.email_service.send_email(message)</code>
登录后复制
登录后复制

TypeScript 示例

<code class="language-typescript">class EmailService {
    sendEmail(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private emailService: EmailService;

    constructor() {
        this.emailService = new EmailService();
    }

    notify(message: string): void {
        this.emailService.sendEmail(message);
    }
}</code>
登录后复制
登录后复制

问题:

  1. 紧密耦合:Notification直接依赖于EmailService
  2. 扩展性有限:切换到SMSService需要修改Notification

含浸

Python 示例

<code class="language-python">from abc import ABC, abstractmethod

class MessageService(ABC):
    @abstractmethod
    def send_message(self, message):
        pass

class EmailService(MessageService):
    def send_message(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self, message_service: MessageService):
        self.message_service = message_service

    def notify(self, message):
        self.message_service.send_message(message)

# Usage
email_service = EmailService()
notification = Notification(email_service)
notification.notify("Hello, Dependency Inversion!")</code>
登录后复制
登录后复制

TypeScript 示例

<code class="language-typescript">interface MessageService {
    sendMessage(message: string): void;
}

class EmailService implements MessageService {
    sendMessage(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private messageService: MessageService;

    constructor(messageService: MessageService) {
        this.messageService = messageService;
    }

    notify(message: string): void {
        this.messageService.sendMessage(message);
    }
}

// Usage
const emailService = new EmailService();
const notification = new Notification(emailService);
notification.notify("Hello, Dependency Inversion!");</code>
登录后复制
登录后复制

DIP 的好处:

  • 灵活性:轻松交换实现。
  • 可测试性:使用模拟进行测试。
  • 可维护性:低级模块的更改不会影响高级模块。

  1. 控制反转 (IoC)

IoC 是一种设计原则,其中依赖控制转移到外部系统(框架)而不是在类内进行管理。 传统上,类创建并管理其依赖项。 IoC 逆转了这一点——外部实体注入依赖项。


Python 示例:没有 IoC

<code class="language-python">class SMSService:
    def send_message(self, message):
        print(f"Sending SMS: {message}")

class Notification:
    def __init__(self):
        self.sms_service = SMSService()  # Dependency created internally

    def notify(self, message):
        self.sms_service.send_message(message)</code>
登录后复制

TypeScript 示例:没有 IoC

<code class="language-typescript">class SMSService {
    sendMessage(message: string): void {
        console.log(`Sending SMS: ${message}`);
    }
}

class Notification {
    private smsService: SMSService;

    constructor() {
        this.smsService = new SMSService(); // Dependency created internally
    }

    notify(message: string): void {
        this.smsService.sendMessage(message);
    }
}</code>
登录后复制

没有 IoC 的问题:

  1. 紧密耦合。
  2. 灵活性低。
  3. 困难的测试。

Python 示例:使用 IoC

<code class="language-python">class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self):
        self.email_service = EmailService()

    def notify(self, message):
        self.email_service.send_email(message)</code>
登录后复制
登录后复制

TypeScript 示例:使用 IoC

<code class="language-typescript">class EmailService {
    sendEmail(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private emailService: EmailService;

    constructor() {
        this.emailService = new EmailService();
    }

    notify(message: string): void {
        this.emailService.sendEmail(message);
    }
}</code>
登录后复制
登录后复制

国际奥委会的好处:

  1. 松散耦合。
  2. 轻松实现切换。
  3. 提高了可测试性。

  1. 依赖注入 (DI)

DI 是一种对象从外部源接收其依赖项的技术。 这是 IoC 的实际实现,通过以下方式注入依赖项:

  1. 构造函数注入
  2. 二传手注射
  3. 接口注入

Python 示例:DI 框架(使用 injector 库)

<code class="language-python">from abc import ABC, abstractmethod

class MessageService(ABC):
    @abstractmethod
    def send_message(self, message):
        pass

class EmailService(MessageService):
    def send_message(self, message):
        print(f"Sending email: {message}")

class Notification:
    def __init__(self, message_service: MessageService):
        self.message_service = message_service

    def notify(self, message):
        self.message_service.send_message(message)

# Usage
email_service = EmailService()
notification = Notification(email_service)
notification.notify("Hello, Dependency Inversion!")</code>
登录后复制
登录后复制

TypeScript 示例:DI 框架(使用 tsyringe 库)

<code class="language-typescript">interface MessageService {
    sendMessage(message: string): void;
}

class EmailService implements MessageService {
    sendMessage(message: string): void {
        console.log(`Sending email: ${message}`);
    }
}

class Notification {
    private messageService: MessageService;

    constructor(messageService: MessageService) {
        this.messageService = messageService;
    }

    notify(message: string): void {
        this.messageService.sendMessage(message);
    }
}

// Usage
const emailService = new EmailService();
const notification = new Notification(emailService);
notification.notify("Hello, Dependency Inversion!");</code>
登录后复制
登录后复制

DI 的好处:

  • 简化测试。
  • 提高了可扩展性。
  • 增强的可维护性。

这个详细的解释阐明了 DIP、IoC 和 DI 之间的关系和区别,强调了它们对构建健壮且可维护的软件的个人贡献。

以上是分解依赖倒置、IoC 和 DI的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板