马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
C++那些事之依赖注入
近来星球内里有个小搭档让更新一下依赖注入,于是写出了这篇文章,来从现实的例子讲授,本文会讲授一些原理与实现,完备的实当代码懒人版放在星球中,我们开始正文。
大纲:
依赖注入是一种常用的计划模式,通常会接纳接口/模版的方式进步代码的可测性与维护性,下面我们来举个例子。
假设有一个用户服务类UserService,必要通过HTTP客户端与远程服务器举行通讯,在这种环境下我们大概会写出如下三种实现。
1.直接依赖
UserService内部直接依赖HttpClient,比方:
- class HttpClient {
- public:
- std::string Get(const std::string& url);
- void Post(const std::string& url, const std::string& data);
- };
- class UserService {
- private:
- HttpClient m_httpClient;
- };
复制代码 UserService内部通常会有一些方法去利用m_httpClient,这种方式简单粗暴,但是UserService与详细的HttpClient相耦合,导致难以更换依赖对象,也难以举行单位测试。
于是引出了反面两个方法。
2.接口依赖注入
我们的目的是渴望测试的时间很方便的测试,而不必要创建一个详细的类,可以由用户mock出一个类去测试,那么我们可以想到接口,将HttpClient抽出来,得到:
- struct IHttpClient {
- virtual std::string Get(const std::string& url) = 0;
- virtual void Post(const std::string& url, const std::string& data) = 0;
- virtual ~IHttpClient() = default;
- };
- class UserService {
- private:
- std::unique_ptr<IHttpClient> m_httpClient;
- };
复制代码 那么在测试的时间便可以mock出一个client举行测试,比方:
- class MockHttpClient : public IHttpClient {
- public:
- MOCK_METHOD(std::string, Get, (const std::string& url), (override));
- MOCK_METHOD(void, Post, (const std::string& url, const std::string& data), (override));
- };
- auto mockHttpClient = std::make_unique<MockHttpClient>();
- UserService userService(std::move(mockHttpClient));
复制代码 颠末以上改造,我们可以做到:
- 在 .cc 文件中隐蔽实现细节
- 针对抽象接口工作
- 在对象构造期间注入依赖项
3.模版依赖注入
模板依赖注入通过C++模板技能,将依赖对象作为模板参数转达给UserService。在实例化模板时,指定详细的HTTP客户端实现。这种方法在编译时办理依赖标题,无需虚函数调用,进步了性能。同时,也使得UserService类可以机动地与差别的HTTP客户端实现举行集成,而且易于举行单位测试。
- template <typename THttpClient>
- class UserService {
- private:
- THttpClient m_httpClient;
- };
复制代码 在这种环境下比力好测试,比方:
- UserService<MockHttpClient> userService;
复制代码 这种方式有如下优点:
- 在模板实例化期间注入依赖项
- 无需假造调用(注意 THttpClient 不是接口,因此可以在编译时剖析调用)
以上便是本节要讲的全部内容,本节完备代码放于星球,接待订阅下载!
跟我一起实践写代码,戳这里呀~
往期保举:
热度更新,手把手实现工业级线程池
|