依赖注入的好处和不用依赖注入的对比
如下例子:Tire:轮子;Bottom:底盘;Framework:箱体;Luggage:行李箱;
行李箱的设计和箱体(依赖)有关,箱体大小依赖底盘(和底盘有关),底盘依赖轮子
这是没有用注入思想的方式:我们最后要调用Luggage类的move的时候,需要new LUGGAGE(30).move();
这是采用依赖注入的思想:
两者对比,发现貌似依赖注入的写法更复杂,或者并不觉得有什么必要这样写。特别最后调用Luggage类的move的时候还需要new那么多个对象
Tire tire = new Tire();
Bottom bottom = new Bottom(tire);
Framework framework = new Framework(bottom);
Luggage luggage = new Luggage(framework);
luggage.move();
假如我们的需求出现变化,如下:
Tire 类需要新增 “材质(material)” 属性。
那么,不采用注入方式写法(如上第一种),需要依次修改如下代码:
1. 第一步:修改 Tire 类
public class Tire {private int size;private String material; // 新增材质属性// 构造函数需要同时传入 size 和 materialTire(int size, String material) {this.size = size;this.material = material;}
}
- 第二步:修改直接依赖 Tire 的 Bottom 类
public class Bottom {private Tire tire;// 构造函数需要新增 material 参数,并传递给 TireBottom(int size, String material) {this.tire = new Tire(size, material); // 必须传入 material}
}
```第三步:修改依赖 Bottom 的 Framework 类,Framework 类创建 Bottom 时,必须传递 material 参数,否则无法实例化 Bottom```java
public class Framework {private Bottom bottom;// 构造函数需要新增 material 参数,并传递给 BottomFramework(int size, String material) {this.bottom = new Bottom(size, material); // 必须传入 material}
}
第四步:修改依赖 Framework 的 Luggage 类
Luggage 类创建 Framework 时,必须传递 material 参数,否则无法实例化 Framework。
public class Luggage {private Framework framework;// 构造函数需要新增 material 参数,并传递给 FrameworkLuggage(int size, String material) {this.framework = new Framework(size, material); // 必须传入 material}public void move() {// ... 原有逻辑}
}
第五步:修改最上层的调用代码
创建 Luggage 时,必须传入新增的 material 参数。
int size = 30;
String material = "rubber"; // 新增材质参数
Luggage luggage = new Luggage(size, material); // 必须传入 material
luggage.move();
而采用依赖注入的方式,需要如下修改
步骤 1:修改 Tire 类,新增材质属性:
public class Tire {private int size;private String material; // 新增“材质”属性// 构造函数接收 size 和 materialTire(int size, String material) {this.size = size;this.material = material;}
}
步骤 2:在注入的入口处,传递带材质的 Tire
所有对象的创建和依赖注入,都集中在 “组装环节”(通常是程序入口或专门的配置类),只需在这里传递新的 material 参数即可:
public class Main {public static void main(String[] args) {// 1. 创建“带材质的 Tire”Tire tire = new Tire(20, "rubber"); // 传入 size=20,material="rubber"// 2. 注入 Tire 到 BottomBottom bottom = new Bottom(tire);// 3. 注入 Bottom 到 FrameworkFramework framework = new Framework(bottom);// 4. 注入 Framework 到 LuggageLuggage luggage = new Luggage(framework);// 5. 调用方法luggage.move();}
}
对比优势:依赖注入如何避免 “层层修改”
硬编码 new 的方式:Tire 新增 material 后,Bottom、Framework、Luggage 的构造函数都要新增参数,且每个类都要修改 new 的逻辑,形成连锁修改。
依赖注入的方式:只有 Tire 本身和 “注入的入口处” 需要修改(传递 material),中间的 Bottom、Framework、Luggage 完全无需改动 —— 因为它们的依赖是 “外部注入” 的,而非自己硬编码 new 出来的。
这种方式体现了控制反转(IoC):对象的创建和依赖传递由 “外部容器 / 组装代码” 控制,而非对象内部硬编码,从而大幅减少修改范围。