控制反转依赖注入
解释:
控制反转:
控制反转其实并不是某项具体的实现技术,它是一种思路(或者是设计理念)。
谁控制谁,控制什么:我们直接通过new进行创建对象,是程序主动去创建依赖对象;而我们现在有专门一个容器来创建这些对象,即由容器来控制和管理对象;
为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;这种注入的方式就是依赖注入
思考:
●谁依赖于谁:当然是应用程序依赖于容器;
●为什么需要依赖:应用程序需要容器来提供对象需要的外部资源;
●谁注入谁:很明显是容器注入应用程序某个对象,应用程序依赖的对象;
●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
问题:为什么要搞控制反转,依赖注入?
解耦
举例:假如老王是少林寺的主持,他想让小二和尚去扫达摩院的地,代码可以这样实现。
小二类的代码如下所示:
public class xiaoEr
{
public void saoDi()
{
Console.WriteLine ("小二我在扫达摩院的地");
}
}
老王类的代码如下所示
public class laoWang {
public void mingLing()
{
new xiaoEr().saoDi();
}
}
测试类的代码如下所示:
public class test
{
public static void main(String[] args)
{
laoWang laowang = new laoWang();
laowang.mingLing();
}
}
如果想换个人怎么办?是不是又要在老王类里面再去new一个对象?
这时候如果有个容器在中间管理,是不是就做到控制反转?是不是就做到了解耦?
控制反转的三种方式:
1)基于构造函数。
实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。
老王类的代码修改如下所示:
public class laoWang
{
private heShang saoDiSeng;
public laoWang(heShang saoDiSeng) {
this.saoDiSeng = saoDiSeng;
}
public void mingLing() {
this.saoDiSeng.saoDi();
}
}
测试类的代码修改如下所示:
public class Test
{
public static void main(String[] args)
{
laoWang laowang = new laoWang(new xiaoSan());
laowang.mingLing();
}
}
2)基于 set 方法。
实现特定属性的 public set 方法,让外部容器调用传入所依赖类型的对象。
老王类的代码修改如下所示:
public class laoWang
{
private heShang saoDiSeng;
public heShang getSaoDiSeng()
{
return saoDiSeng;
}
public void setSaoDiSeng(heShang saoDiSeng)
{
this.saoDiSeng = saoDiSeng;
}
public void mingLing()
{
this.getSaoDiSeng().saoDi();
}
}
3)基于接口。
实现特定接口以供外部容器注入所依赖类型的对象,这种做法比较构造函数和 set 方法更为复杂,不做赘述。