C++中的依赖注入:初学者完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

什么是C++中的依赖注入以及为什么需要它?

\n\n

依赖注入(DI)是面向对象编程的关键原则之一,它能使代码更加灵活、可测试和易于维护。如果你是C++新手,听说过"松耦合"或"控制反转"等术语但尚未完全理解,那么本文就是为你准备的。

\n\n

简单来说,依赖注入是一种技术,对象从外部获取其依赖项,而不是自己创建它们。类不再自己创建其他类的对象,而是通过构造函数、setter方法或接口将这些对象"注入"到类中。

\n\n

问题:紧耦合

\n\n

假设你正在编写一个发送通知的应用程序。没有DI时,你的代码可能如下所示:

\n\n
#include <iostream>\n#include <string>\n\nclass EmailService {\npublic:\n    void send(const std::string& message) {\n        std::cout << "发送邮件:" << message << std::endl;\n    }\n};\n\nclass Notification {\nprivate:\n    EmailService emailService;  // 硬依赖!\npublic:\n    void notify(const std::string& msg) {\n        emailService.send(msg);\n    }\n};\n\nint main() {\n    Notification notif;\n    notif.notify("Hello, World!");\n    return 0;\n}
\n\n

在这个例子中,Notification类与EmailService紧密耦合。如果你想添加短信通知或日志记录,就必须重写Notification类。这样的代码难以测试、扩展和维护。

\n\n

解决方案:依赖注入

\n\n

为了解决紧耦合问题,我们使用DI。核心思想是为通知服务定义一个接口(抽象类),并从外部将其传递给Notification类。

\n\n

步骤1:创建抽象接口

\n\n
#include <iostream>\n#include <string>\n#include <memory>\n\n// 所有通知服务的抽象接口\nclass IMessageService {\npublic:\n    virtual ~IMessageService() = default;\n    virtual void send(const std::string& message) = 0;\n};
\n\n

步骤2:实现具体服务

\n\n
class EmailService : public IMessageService {\npublic:\n    void send(const std::string& message) override {\n        std::cout << "📧 邮件:" << message << std::endl;\n    }\n};\n\nclass SMSService : public IMessageService {\npublic:\n    void send(const std::string& message) override {\n        std::cout << "📱 短信:" << message << std::endl;\n    }\n};
\n\n

步骤3:通过构造函数注入依赖

\n\n
class Notification {\nprivate:\n    std::unique_ptr<IMessageService> service;  // 依赖从外部注入\npublic:\n    // 通过构造函数注入(Constructor Injection)\n    Notification(std::unique_ptr<IMessageService> svc) \n        : service(std::move(svc)) {}\n    \n    void notify(const std::string& msg) {\n        service->send(msg);\n    }\n};\n\nint main() {\n    // 创建具体实现\n    auto emailService = std::make_unique<EmailService>();\n    \n    // 将其注入到Notification中\n    Notification notif(std::move(emailService));\n    notif.notify("依赖注入生效!");\n    \n    // 轻松切换为短信\n    auto smsService = std::make_unique<SMSService>();\n    Notification smsNotif(std::move(smsService));\n    smsNotif.notify("现在通过短信发送!");\n    \n    return 0;\n}
\n\n

C++中三种主要的依赖注入方式

\n\n

1. 构造函数注入

\n

最常见且推荐的方式。依赖项在对象创建时传入,并在其生命周期内保持不变。

\n\n
<                

博客

书籍推荐