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

符合依赖注入(DI)却不符合依赖倒置原则?示例代码的setWorker注入属DI吗?

Answers to Your DIP & DI Questions

1. Is setWorker in the bad example Dependency Injection (DI)?

Yes, totally! That’s a textbook case of setter-based dependency injection.

Let’s break it down: Dependency Injection’s core idea is letting an external source supply the dependencies a class needs, instead of the class creating those dependencies itself. In the bad example, the Manager doesn’t instantiate a Worker internally (like writing worker = new Worker()); instead, it accepts a Worker instance through the setWorker method. This fits the exact definition of DI—you’re injecting the dependency from outside the class.

The key caveat here is that while this uses DI, it does not follow the Dependency Inversion Principle (DIP). DIP requires high-level modules (like Manager) to depend on abstractions, not concrete classes. Here, Manager relies directly on the concrete Worker class, so you can’t swap in SuperWorker without modifying Manager’s code (since setWorker only accepts Worker instances, not a shared abstraction).

2. Can a system use DI but violate DIP?

Absolutely—DI and DIP are related but separate concepts:

  • DI is a technique for managing how dependencies are supplied to a class.
  • DIP is a design principle that dictates what types of dependencies you should rely on (abstractions over concretions).

Here’s a clear example of code that uses DI but breaks DIP:

// Concrete database class with no abstract interface
class MySQLDatabase {
    public void saveRecord(String data) {
        // Logic to write data to MySQL
    }
}

// High-level service using DI but dependent on a concrete class
class OrderService {
    private MySQLDatabase db;

    // Constructor injection (this is DI!)
    public OrderService(MySQLDatabase db) {
        this.db = db;
    }

    public void saveOrder(String orderDetails) {
        db.saveRecord(orderDetails);
    }
}

In this case:

  • We’re using constructor-based DI to pass the MySQLDatabase into OrderService—no internal instantiation, so that’s valid DI.
  • But we’re violating DIP because OrderService depends directly on the concrete MySQLDatabase class, not an abstraction like a Database interface. If we later want to switch to PostgreSQL, we’d have to rewrite the OrderService constructor and all references to MySQLDatabase, which breaks flexibility and the open/closed principle.

To fix this and align with DIP, we’d define a Database interface, have MySQLDatabase (and other database implementations) implement it, and make OrderService depend on the Database interface instead of the concrete class.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:12:29