You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

依赖注入与简单接口使用有何区别?

Hey there! Great question—let’s break this down using your code as a starting point, since you’ve already got the foundation of interfaces right.

First, let’s clarify: what you’ve written is a solid use of interfaces to abstract logging behavior, but it’s not yet dependency injection (DI). The key difference boils down to how your code gets access to the ILogger instance and who’s in control of that dependency.

Let’s break down the core distinctions:

1. Who controls the dependency?

  • Your current setup uses a global ILogger variable in Application.h. That means any code in the application has to reach out to this global to use logging. The application itself doesn’t receive the logger—it has to go fetch it.
  • With dependency injection, the dependency (your ILogger implementation) is passed into the code that needs it, rather than being pulled from a global, singleton, or hardcoded source. For example, instead of relying on a global, your Application class would take an ILogger as a constructor parameter:
    class Application {
    private:
        ILogger& m_logger; // Hold a reference to the injected logger
    public:
        // Inject the logger through the constructor
        Application(ILogger& logger) : m_logger(logger) {}
    
        void run() {
            m_logger.writeMsg("Application started!");
            // ... rest of your app logic
        }
    };
    
    Then, when you start your app, you create the logger first and pass it in:
    int main() {
        Application_Logger appLogger;
        Application myApp(appLogger); // Inject the logger here
        myApp.run();
    
        // For testing, you'd do this instead:
        // Test_Logger testLogger;
        // Application testApp(testLogger);
        // testApp.run();
    }
    

2. Coupling between components

  • Your global approach keeps your Application tightly coupled to that global variable. Even though you’re using an interface, changing which logger is used requires modifying the global’s assignment (or relying on some external code to set it). If you ever need multiple logger instances (e.g., one for business logic, one for errors), you’d have to add more globals—messy and hard to maintain.
  • DI eliminates this tight coupling. Your Application only cares that it gets something that implements ILogger; it has no idea whether it’s an Application_Logger, Test_Logger, or even a new File_Logger you write later. You can swap implementations without touching the Application code at all.

3. Testability

  • With your global setup, testing the Application’s logging behavior is tricky. You’d have to set the global logger to a Test_Logger before running tests, then reset it afterward—easy to forget, and risky if tests run in parallel (they might overwrite each other’s logger).
  • With DI, testing is trivial. You just pass a Test_Logger directly to the Application instance in your test code. No globals to mess with, no state leaks between tests—each test gets its own isolated logger.

4. Flexibility and scalability

  • Global interfaces work for small apps, but they fall apart as your code grows. What if you need different loggers for different parts of the app? Or want to configure logging based on environment variables? Globals make this hard.
  • DI lets you handle these scenarios seamlessly. You can create different logger instances for different components, configure them dynamically at startup, or even swap implementations while the app is running—all without changing the code that uses the logger.

To sum it up:

Using an interface is about defining a contract for behavior. Dependency injection is about how you deliver an implementation of that contract to the code that needs it. Your current code uses the contract, but it’s still relying on a global to get the implementation. DI flips that: the implementation is given to the code, rather than the code going to find it.

This might feel like a small change at first, but it makes your code far more modular, testable, and easy to maintain as it grows.

内容的提问来源于stack exchange,提问作者Dominique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:17:35