C++中的依赖注入:初学者简易指南

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

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

开始课程

C++中的依赖注入简介



当你刚开始学习C++时,你会编写简单的程序,其中类直接创建自己的依赖。例如,Car类自己创建了一个Engine对象。这对于小型项目是可行的,但当代码规模扩大时,这种方法会导致严重问题:代码变得高度耦合,难以测试和修改。



依赖注入(DI)是一种设计模式,其中对象从外部获取其依赖,而不是自己创建它们。这是SOLID关键原则之一,即依赖反转原则(Dependency Inversion Principle)。



在本文中,我们将探讨C++中的依赖注入是什么、为什么需要它,以及如何在实际中应用它。您将看到这种模式如何使代码变得灵活、可测试和可维护。



为什么没有DI会很糟糕:紧耦合问题



假设您正在编写一个智能家居管理系统。有一个SmartLight类,它控制一个灯泡。在简单的实现中,它自己创建了一个Bulb对象:



#include <iostream>#include <string>

class Bulb {public: void turnOn() { std::cout << "灯泡已打开"; } void turnOff() { std::cout << "灯泡已关闭"; }};

class SmartLight {private: Bulb bulb; // 紧耦合依赖public: void activate() { bulb.turnOn(); } void deactivate() { bulb.turnOff(); }};

int main() { SmartLight light; light.activate(); return 0;}


这里有什么问题?



  • 紧耦合:SmartLight与Bulb紧密绑定。如果您想使用另一种灯泡(例如智能LED或Phillips Hue),就必须修改类的代码。
  • 测试困难:在单元测试中,您无法将真实灯泡替换为“模拟对象”(mock)。
  • 违反SRP:SmartLight类做了两件事:控制灯泡和创建它。


这是一个经典的紧耦合(tight coupling)示例,而依赖注入正是为了解决这个问题。



C++中的依赖注入是什么:核心概念



依赖注入(DI)是一种技术,其中对象从外部源获取其依赖(通常通过构造函数、设置器或接口),而不是自己创建它们。核心思想是:“不要问你需要什么——别人会给你”。



在C++中,DI通过以下方式实现:



  • 接口(抽象类):依赖通过抽象类型声明,而不是具体类。
  • 带参数的构造函数:依赖通过构造函数传递(最常见的方式)。
  • 设置器:依赖在对象创建后设置。
  • 依赖容器:自动创建和注入依赖的特殊库(例如boost.di)。


让我们使用DI重写智能灯的例子:



#include <iostream>#include <memory>

// 灯泡的抽象接口class IBulb {public: virtual void turnOn() = 0; virtual void turnOff() = 0; virtual ~IBulb() = default;};

// 具体实现:普通灯泡class Bulb : public IBulb {public: void turnOn() override { std::cout << "灯泡已打开"; } void turnOff() override { std::cout << "灯泡已关闭"; }};

// 另一种实现:LED灯泡class LedBulb : public IBulb {public: void turnOn() override { std::cout << "LED灯泡已打开"; } void turnOff() override {

博客

书籍推荐