依赖注入as a cure
When an object uses a singleton, it injects a hidden dependency into the object. Thanks to dependency injection, this dependency is part of the interface, and the service is injected from the outside. Consequently, there is no dependency between the client and the injected service. Typical ways to inject dependencies are constructors, setter members, or template parameters.
The following program shows how you can replace a logger using dependency injection.
/ / dependencyInjection.cpp # include <空间> #包括ude#include class Logger { public: virtual void write(const std::string&) = 0; virtual ~Logger() = default; }; class SimpleLogger: public Logger { void write(const std::string& mess) override { std::cout << mess << std::endl; } }; class TimeLogger: public Logger { using MySecondTick = std::chrono::duration ; long double timeSinceEpoch() { auto timeNow = std::chrono::system_clock::now(); auto duration = timeNow.time_since_epoch(); MySecondTick sec(duration); return sec.count(); } void write(const std::string& mess) override { std::cout << std::fixed; std::cout << "Time since epoch: " << timeSinceEpoch() } }; class Client { public: Client(std::shared_ptr log): logger(log) {} void doSomething() { logger->write("Message"); } void setLogger(std::shared_ptr log) { logger = log; } private: std::shared_ptr logger; }; int main() { std::cout << '\n'; Client cl(std::make_shared ()); // (1) cl.doSomething(); cl.setLogger(std::make_shared ()); // (2) cl.doSomething(); cl.doSomething(); std::cout << '\n'; }
The clientclsupports the constructor (1) and the member functionsetLogger(2) to inject the logger service. In contrast to theSimpleLogger,TimeLoggerincludes the time since epoch in its message (seeFigure 3.1).
Figure 3.1依赖注入