C++那些事之依赖注入

[复制链接]
发表于 2026-2-21 10:07:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
C++那些事之依赖注入

近来星球内里有个小搭档让更新一下依赖注入,于是写出了这篇文章,来从现实的例子讲授,本文会讲授一些原理与实现,完备的实当代码懒人版放在星球中,我们开始正文。
大纲:


  • 直接依赖
  • 接口依赖注入
  • 模版依赖注入
依赖注入是一种常用的计划模式,通常会接纳接口/模版的方式进步代码的可测性与维护性,下面我们来举个例子。
假设有一个用户服务类UserService,必要通过HTTP客户端与远程服务器举行通讯,在这种环境下我们大概会写出如下三种实现。

1.直接依赖

UserService内部直接依赖HttpClient,比方:
  1. class HttpClient {
  2.  public:
  3.   std::string Get(const std::string& url);
  4.   void Post(const std::string& url, const std::string& data);
  5. };
  6. class UserService {
  7.  private:
  8.   HttpClient m_httpClient;
  9. };
复制代码
UserService内部通常会有一些方法去利用m_httpClient,这种方式简单粗暴,但是UserService与详细的HttpClient相耦合,导致难以更换依赖对象,也难以举行单位测试。
于是引出了反面两个方法。
2.接口依赖注入

我们的目的是渴望测试的时间很方便的测试,而不必要创建一个详细的类,可以由用户mock出一个类去测试,那么我们可以想到接口,将HttpClient抽出来,得到:
  1. struct IHttpClient {
  2.   virtual std::string Get(const std::string& url) = 0;
  3.   virtual void Post(const std::string& url, const std::string& data) = 0;
  4.   virtual ~IHttpClient() = default;
  5. };
  6. class UserService {
  7.  private:
  8.   std::unique_ptr<IHttpClient> m_httpClient;
  9. };
复制代码
那么在测试的时间便可以mock出一个client举行测试,比方:
  1. class MockHttpClient : public IHttpClient {
  2. public:
  3.   MOCK_METHOD(std::string, Get, (const std::string& url), (override));
  4.   MOCK_METHOD(void, Post, (const std::string& url, const std::string& data), (override));
  5. };
  6. auto mockHttpClient = std::make_unique<MockHttpClient>();
  7. UserService userService(std::move(mockHttpClient));
复制代码
颠末以上改造,我们可以做到:


  • 在 .cc 文件中隐蔽实现细节
  • 针对抽象接口工作
  • 在对象构造期间注入依赖项
3.模版依赖注入

模板依赖注入通过C++模板技能,将依赖对象作为模板参数转达给UserService。在实例化模板时,指定详细的HTTP客户端实现。这种方法在编译时办理依赖标题,无需虚函数调用,进步了性能。同时,也使得UserService类可以机动地与差别的HTTP客户端实现举行集成,而且易于举行单位测试。
  1. template <typename THttpClient>
  2. class UserService {
  3.  private:
  4.   THttpClient m_httpClient;
  5. };
复制代码
在这种环境下比力好测试,比方:
  1. UserService<MockHttpClient> userService;
复制代码
这种方式有如下优点:


  • 在模板实例化期间注入依赖项
  • 无需假造调用(注意 THttpClient 不是接口,因此可以在编译时剖析调用)
以上便是本节要讲的全部内容,本节完备代码放于星球,接待订阅下载!
跟我一起实践写代码,戳这里呀~


往期保举:

向量数据库milvus源码分析之开篇

热度更新,手把手实现工业级线程池


回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表