原始场景:
一个行李箱的构建需要从轮子开始做起,如图所示:
原来的代码可能是这样的:(代码不严谨,只是为了展示,望不计小节)
public class luggage{
luggage{
this.frame = new frame();
}
}
public class frame{
frame(){
this.bottom = new bottom();
}
}
public class bottom{
bottom(){
this.tire = new tire();
}
}
public class tire{
tire(){
}
}
如果产品突然说要加一个参数,轮子的大小应该是可以改动的,那么代码可能要改成这样子
public class luggage{
luggage(int size){
this.frame = new frame(size);
}
}
public class frame{
frame(int size){
this.bottom = new bottom(size);
}
}
public class bottom{
bottom(int size){
this.tire = new tire(size);
}
}
public class tire{
tire(int size){
this.size = size;
}
}
如果存在一个类被几千个类所依赖的,那要修改的代码将是不可预估的,也就是说,这种设计代码的方式,代码的耦合度非常高。这时候,就需要控制反转
用依赖注入DI实现控制反转
public luggage{
luggage(frame){
this.frame = frame;//一开始就如此设计,任何参数对于上层来说都是透明的
}
}
最后如此调用代码
int size = 30;
tire t = new tire(size);
bottom b = new bottom(t);
frame f = new frame(b);
luggage l = new luggage(f);
l.move();//现在箱子可以自由推动辣
上面这种思想,是依赖倒置原则
依赖注入的方式
DI 注入依赖最主流的方式,主要有以下几种:
- setter
- interface
- constructor 我们刚才实现的就是这种方式
- annotation
IOC容器的好处
- 避免在各处使用new来创建类,并且可以做到统一维护
- 创建实例的时候可以不需要了解其中的细节
- 反射+工厂模式的合体,满足开闭原则