IoC控制反转理解
2017-05-13 16:14
204 查看
IoC(Inverse of Control),即控制反转,也叫做依赖注入。是面向对象设计的一个重要的概念。它提出了将被调用对象的控制权由调用者转移到第三方控制器上。这样以满足软件开发中的依赖倒置(DI)原则。
一个电影为例:
《墨攻》中一片段:守城士兵问刘德华扮演的墨者革离“来者何人?”,革离回答说“墨者革离”。现在考虑这样一个剧本:
可以看到,演员直接侵入了剧本之中,这样假设不再由刘德华扮演革离,那么剧本将不再适用。为此,我们实现一个革离的接口,通过接口展开剧情:
这样的Action、LiuDeHua、GeLi关系如下:
但是我们可以看到,LiuDeHua还是出现在剧本之中,脚本最终还是依赖于具体的扮演者。那么如何才能让Action脚本与具体的扮演者无关呢?这时候我们可以考虑一个导演,让他来控制GeLi的扮演者,即由导演决定GeLi的具体实现。如下:
此时,我们在不经意间,已经完成了控制反转:原本在脚本(调用者)之中就要给定具体的演员(被调用者),此时,我们将演员的决定权交由导演(第三方控制器)决定。以上便是控制反转的介绍。在实践中,我们通常有三种方式实现控制反转:
构造函数注入
属性注入
依赖注入
1.构造函数注入:
在构造函数中将接口的实现类以参数的方式传入。例如:
但是存在一个弊端就是,演员刘德华在脚本开始拍摄时就一直在场。这显然是不可取的(因为这会占用计算机的内存)。所以一个好的方法是让演员在有戏的地方出现:
2.属性注入:
其实就是通过一个getter和一个setter完成对相关接口的实现类的传入:
class Action{
private GeLi geli;
public Action(){}
//属性注入
public void setGeLi(GeLi geli){
this.geli=geli;
}
public void gateAsk(){
//引入接口展开剧情
GeLi geli=new LiuDeHua();
geli.responseAsk();
}
}
public class Director{
GeLi geli=new LiuDeHua();
Action action=new Action();
action.setGeLi(geli);
action.gateAsk();
}
3.接口注入:
其实就是就是将所有依赖注入的方法集合到一个接口中,然后通过实现接口方法来实现接口实现类的传入。
本文转自http://stamen.iteye.com/blog/1489223/,在此感谢原著作者。
一个电影为例:
《墨攻》中一片段:守城士兵问刘德华扮演的墨者革离“来者何人?”,革离回答说“墨者革离”。现在考虑这样一个剧本:
class Action{ public void gateAsk(){ //演员直接侵入剧本 LiuDeHua ldh=new LiuDeHua(); ldh.responseAsk(); } }
可以看到,演员直接侵入了剧本之中,这样假设不再由刘德华扮演革离,那么剧本将不再适用。为此,我们实现一个革离的接口,通过接口展开剧情:
class Action{ public void gateAsk(){ //引入接口展开剧情 GeLi geli=new LiuDeHua(); geli.responseAsk(); } }
这样的Action、LiuDeHua、GeLi关系如下:
但是我们可以看到,LiuDeHua还是出现在剧本之中,脚本最终还是依赖于具体的扮演者。那么如何才能让Action脚本与具体的扮演者无关呢?这时候我们可以考虑一个导演,让他来控制GeLi的扮演者,即由导演决定GeLi的具体实现。如下:
此时,我们在不经意间,已经完成了控制反转:原本在脚本(调用者)之中就要给定具体的演员(被调用者),此时,我们将演员的决定权交由导演(第三方控制器)决定。以上便是控制反转的介绍。在实践中,我们通常有三种方式实现控制反转:
构造函数注入
属性注入
依赖注入
1.构造函数注入:
在构造函数中将接口的实现类以参数的方式传入。例如:
class Action{ private GeLi geli; public Action(GeLi geli){ this.geli=geli; } public void gateAsk(){ //引入接口展开剧情 GeLi geli=new LiuDeHua(); geli.responseAsk(); } } public class Director{ GeLi geli=new LiuDeHua(); Action action=new Action(geli); action.gateAsk(); }
但是存在一个弊端就是,演员刘德华在脚本开始拍摄时就一直在场。这显然是不可取的(因为这会占用计算机的内存)。所以一个好的方法是让演员在有戏的地方出现:
2.属性注入:
其实就是通过一个getter和一个setter完成对相关接口的实现类的传入:
class Action{
private GeLi geli;
public Action(){}
//属性注入
public void setGeLi(GeLi geli){
this.geli=geli;
}
public void gateAsk(){
//引入接口展开剧情
GeLi geli=new LiuDeHua();
geli.responseAsk();
}
}
public class Director{
GeLi geli=new LiuDeHua();
Action action=new Action();
action.setGeLi(geli);
action.gateAsk();
}
3.接口注入:
其实就是就是将所有依赖注入的方法集合到一个接口中,然后通过实现接口方法来实现接口实现类的传入。
/** * ActorArrange接口 */ public interface ActorArrange { public void setGeLi(GeLi geli); } class Action implements ActorArrange{ private GeLi geli; public Action(){} //属性注入 public void setGeLi(GeLi geli){ this.geli=geli; } public void gateAsk(){ //引入接口展开剧情 GeLi geli=new LiuDeHua(); geli.responseAsk(); } } public class Director{ GeLi geli=new LiuDeHua(); Action action=new Action(); action.setGeLi(geli); action.gateAsk(); }这样,我们成功地将控制权转移到了Director上,使得Action只专注于拍摄。但是总得工作量并没有减少啊!如何实现这些演员分配工作的自动化呢?由此,我们引入了第三方容器。它帮助完成类的初始化与装配工作,让开发者从这些底层实现类的实例化、依赖关系装配等工作中脱离出来,专注于更有意义的业务逻辑开发工作。
本文转自http://stamen.iteye.com/blog/1489223/,在此感谢原著作者。
相关文章推荐
- 理解IoC及控制反转
- 关于IoC(控制反转,依赖注入)的理解
- 有史以来最容易理解的控制反转(IoC)与注入依赖(DI)
- 控制反转(IOC)/依赖注入(DI)理解
- laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)
- Spring IoC(控制反转)和DI(依赖注入)的理解
- 深度理解依赖注入(Dependence Injection)(IOC,Inversion of control,控制反转)
- 深入理解IOC控制反转及应用实例
- Spring 深入理解IOC(控制反转)和DI(依赖注入)
- 代码的演化-DI(理解依赖注入di,控制反转ioc)
- 透彻理解IoC(控制反转)
- 理解Java Spring核心功能之一:控制反转容器(IOC Container)
- 如何理解spring中的IOC(控制反转)、DI(依赖注入)?
- Spring实现控制反转(IOC)的三种方式(零)——理解IOC
- 通过laravel理解IoC(控制反转)容器和DI(依赖注入)
- 我对IOC控制反转,依赖注入原理的理解
- Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)
- 控制反转(IOC) 和依赖注入(DI) 的理解
- 控制反转(IOC) 和依赖注入(DI) 的理解
- Spring控制反转(IoC)的理解