透透彻彻IoC(你没有理由不懂!)

上传人:cl****1 文档编号:512743584 上传时间:2022-08-25 格式:DOCX 页数:8 大小:99.03KB
返回 下载 相关 举报
透透彻彻IoC(你没有理由不懂!)_第1页
第1页 / 共8页
透透彻彻IoC(你没有理由不懂!)_第2页
第2页 / 共8页
透透彻彻IoC(你没有理由不懂!)_第3页
第3页 / 共8页
透透彻彻IoC(你没有理由不懂!)_第4页
第4页 / 共8页
透透彻彻IoC(你没有理由不懂!)_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《透透彻彻IoC(你没有理由不懂!)》由会员分享,可在线阅读,更多相关《透透彻彻IoC(你没有理由不懂!)(8页珍藏版)》请在金锄头文库上搜索。

1、引述:loC (控制反转:In verse of Co ntrol)是Spr ing容器的内核,AOP、声明式事务等功能在此基础上开花结果。但是loC这个重要的概念却比较晦涩隐讳,不容易让 人望文生义,这不能不说是一大遗憾。不过loC确实包括很多内涵,它涉及代码解耦、设 计模式、代码优化等问题的考量,我们打算通过一个小例子来说明这个概念。通过实例理解IoC的概念贺岁大片在中国已经形成了一个传统,每到年底总有多部贺岁大片纷至沓来让人应接不 暇。在所有贺岁大片中,张之亮的墨攻算是比较出彩的一部。该片讲述了战国时期墨家 人革离帮助梁国反抗赵国侵略的个人英雄主义故事,恢宏壮阔、浑雄凝重的历史场面相当震

2、 撼。其中有一个场景:当刘德华所饰演的墨者革离到达梁国都城下,城上梁国守军问到:“来 者何人? ”刘德华回答:“墨者革离! ”我们不妨通过一个Java类为这个“城门叩问”的场景进 行编剧,并借此理解IoC的概念:代码清单3-1 MoAttack :通过演员安排剧本Java代码汀1.public class MoAttack 2.public void cityGateAsk()3.演员直接侵入剧本4.LiuDeHua Idh = new LiuDeHua();5.ldh.responseAsk(墨者革离!);6.7.MoAttack我们会发现以上剧本在处,作为具体角色饰演者的刘德华直接侵入到剧

3、本中,使剧本 和演员直接耦合在一起(图3-1 )。LiuDeHua-FdtyGateAsk Q: void-FresponseAsk Q: vcdd图齐1剧本和演员直接耦合一个明智的编剧在剧情创作时应围绕故事的角色进行,而不应考虑角色的具体饰演者, 这样才可能在剧本投拍时自由地遴选任何适合的演员,而非绑定在刘德华一人身上。通过以 上的分析,我们知道需要为该剧本主人公革离定义一个接口:代码清单3-2 MoAttack:引入剧本角色Java代码X1. public class MoAttack 2.public void cityGateAsk()3.4.引入革离角色接口5.GeLi geli =

4、 new LiuDeHua();6.7.通过接口开展剧情8.geli.responseAsk(”墨者革离! ”);9.10.在处引入了剧本的角色一一革离,剧本的情节通过角色展开,在拍摄时角色由演员饰 演,如处所示。因此墨攻、革离、刘德华三者的类图关系如图32所示:可是,从图3 2中,我们可以看出MoAttack同时依赖于GeLi接口和LiuDeHua类,并 没有达到我们所期望的剧本仅依赖于角色的目的。但是角色最终必须通过具体的演员才能完 成拍摄,如何让LiuDeHua和剧本无关而又能完成GeLi的具体动作呢?当然是在影片投拍 时,导演将LiuDeHua安排在GeLi的角色上,导演将剧本、角色、

5、饰演者装配起来(图3-3)。0-MoAttackA-cityGateAsk (J: void剧本和饰演者解耦了fKte出Movies 0: voidLiiiDeHua-s-nss pons eAsk Q: voidDirectorfKte出Movies 0: void通过引入导演,使剧本和具体饰演者解耦了。对应到软件中,导演像是一个装配器,安排演 员表演具体的角色。现在我们可以反过来讲解loC的概念了。loC(Inverse of Control)的字面意思是控制反 转,它包括两个内容:其一是控制其二是反转那到底是什么东西的“控制”被“反转”了呢?对应到前面的例子,“控制”是指选择GeLi角色

6、 扮演者的控制权;“反转”是指这种控制权从墨攻剧本中移除,转交到导演的手中。对于 软件来说,即是某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。因为loC确实不够开门见山,因此业界曾进行了广泛的讨论,最终软件界的泰斗级人物 Mart in Fowler提出了 DI(依赖注入:Depe nde ncy Injectio n)的概念用以代替loC,即让调 用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接 口实现类的依赖。“依赖注入”这个名词显然比“控制反转”直接明了、易于理解。IoC的类型从注入方法上看,主要可以划分为三种类型:构造函数注入、属性注入

7、和接口注入。Spring 支持构造函数注入和属性注入。下面我们继续使用以上的例子说明这三种注入方法的区别。构造函数注入在构造函数注入中,我们通过调用类的构造函数,将接口实现类通过构造函数变量传入,如 代码清单3-3所示:代码清单3-3 MoAttack:通过构造函数注入革离扮演者Java代码茜1.public class MoAttack 2.private GeLi geli;3.注入革离的具体扮演者4.public MoAttack(GeLi geli)5.this.geli = geli;6.7.public void cityGateAsk()8.geli.responseAsk(”墨

8、者革离! ”);9.10.MoAttack的构造函数不关心具体是谁扮演革离这个角色,只要在处传入的扮演者按剧 本要求完成相应的表演即可。角色的具体扮演者由导演来安排,如代码清单3-4所示: 代码清单3-4 Director:通过构造函数注入革离扮演者Java代码比1.public class Director 2.public void direct()3.指定角色的扮演者4.GeLi geli = new LiuDeHua();5.6.注入具体扮演者到剧本中7.MoAttack moAttack = new MoAttack(geli);8.moAttack.cityGateAsk();9.

9、10.在处,导演安排刘德华饰演革离的角色,并在处,将刘德华“注入”到墨攻的剧本中, 然后开始“城门叩问”剧情的演出工作。属性注入有时,导演会发现,虽然革离是影片墨攻的第一主角,但并非每个场景都需要革离 的出现,在这种情况下通过构造函数注入相当于每时每刻都在革离的饰演者在场,可见并不 妥当,这时可以考虑使用属性注入。属性注入可以有选择地通过Setter方法完成调用类所需依赖的注入,更加灵活方便:代码清单3-5 MoAttack:通过Setter方法注入革离扮演者1. public class MoAttack 2. private GeLi geli;3. 属性注入方法4. public voi

10、dsetGeli(GeLigeli) 5. this.geli = geli;6. 7. public voidcityGateAsk() 8. geli.responseAsk(墨者革离);9. 10. MoAttack在处为geli属性提供一个Setter方法,以便让导演在需要时注入geli的具体 扮演者。代码清单3-6 Director:通过Setter方法注入革离扮演者Java代码比1.public class Director 2.public void direct()3.GeLi geli = new LiuDeHua();4.MoAttack moAttack = new Mo

11、Attack();5.6.调用属性Setter方法注入7.moAttack.setGeli(geli);8.moAttack.cityGateAsk();9.10.和通过构造函数注入革离扮演者不同,在实例化MoAttack剧本时,并未指定任何扮演者, 而是在实例化MoAttack后,在需要革离出场时,才调用其setGeli()方法注入扮演者。按照 类似的方式,我们还可以分别为剧本中其他诸如梁王、巷淹中等角色提供注入的Setter方 法,这样,导演就可以根据所拍剧段的不同,注入相应的角色了。接口注入将调用类所有依赖注入的方法抽取到一个接口中,调用类通过实现该接口提供相应的注 入方法。为了采取接口

12、注入的方式,必须先声明一个ActorArra ngable接口:Java代码1. public interface ActorArrangable 2. void injectGeli(GeLi geli);3. 然后,MoAttack实现ActorArrangable接口提供具体的实现:代码清单3-7 MoAttack:通过接口方法注入革离扮演者1. public class MoAttack implements ActorArrangable 2. private GeLi geli;3. 实现接口方法4. public voidinjectGeli(GeLi geli) 5. this

13、.geli = geli;6. 7. public voidcityGateAsk() 8. geli.responseAsk(墨者革离);9. 10. Director通过ActorArrangable的injectGeli()方法完成扮演者的注入工作。 代码清单3-8 Director:通过接口方法注入革离扮演者Java代码比1.2.3.4.5.6.public class Director public void direct()GeLi geli = new LiuDeHua();MoAttack moAttack = new MoAttack(); moAttack. injectG

14、eli (geli);moAttack.cityGateAsk();7.8.由于通过接口注入需要额外声明一个接口,增加了类的数目,而且它的效果和属性注入 并无本质区别,因此我们不提倡采用这种方式。通过容器完成依赖关系的注入虽然MoAttack和LiuDeHua实现了解耦,MoAttack无须关注角色实现类的实例化工作, 但这些工作在代码中依然存在,只是转移到Director类中而已。假设某一制片人想改变这一 局面,在选择某个剧本后,希望通过一个海选”或者第三中介机构来选择导演、演员,让他 们各司其职,那剧本、导演、演员就都实现解耦了。所谓媒体“海选”和第三方中介机构在程序领域即是一个第三方的容器,它帮助完成类的初 始化与装配工作,让开发者从这些底层实现类的实例化、依赖关系装配等工作中脱离出来, 专注于更有意义的业务逻辑开发工作。这无疑是一件令人向往的事情,Spring就是这样的 一个容器,它通过配置文件或注解描述类和类之间的依赖关系,自动完成类的初始化和依赖 注入的工作。下面是Spring配置文件的对以上实例进行配置的配置文件片断:Xml代码茜1. v?xml version=1.0 encoding=UTF-8 ?2. vbeans xmlns=http:/www.springframework

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号