Inversion of Control Containers.docx
- 文档编号:13958974
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:19
- 大小:28.34KB
Inversion of Control Containers.docx
《Inversion of Control Containers.docx》由会员分享,可在线阅读,更多相关《Inversion of Control Containers.docx(19页珍藏版)》请在冰点文库上搜索。
InversionofControlContainers
InversionofControlContainers
InversionofControlcontainers(akaIoC)havebeenalloftherageinthepastyear.YoucanhardlyturnaroundonthewebwithouthittingsomebodysomewheretoutingsomeIoCsolution/framework/silverbullet.ThisblogentrytalksaboutmyownexperienceswithIoCoverthepast4months,andcomparesmyownviewpointofwhatIoCshouldbetowhat'savailableinthreepopularIoCimplementations:
Hivemind,PicoContainer,andSpring.Examplesareshownbased(veryloosely!
)onmyownrecentwork,sothatwe'reatleastpartiallygroundedinreality.
ANOTEandaRANT:
Irefusetousetheterm"dependencyinjection"(akaDI),becausethistermonlycoversoneaspectofwhatanIoCcontainerdoesforthesoftwaredeveloper.Ifyou'redesperatetogetajobatThoughtWorks,byallmeansfeelfreetoflingDIaroundatwill,butsomeofuspreferaccuracytocow-towingtocreatorsofmarketingblurbs.Ontheotherhand,weshouldallcountourselvesfortunatethatBeckwasn'tinvolvedintherenaming-attempt,orwe'dalllikeyhavetodealwithanamelikeeXtremeContainerorsomethingequallynausea-inducing.FortunatelyalltheXPersseemtoobusystillpropogatingIdiotDrivenDevelopment....
WhatisIoC?
AdefinitionofIoCultimatelycomesdowntoafewthings.Atahighlevel,I'dsay:
∙There'sacontainer,whichmanagesobjectsforyou.I'llgenerallycallittheIoCContainerorjust"thecontainer".
∙Thecontainergenerallycontrolscreationofobjects.AsIliketosay,itdoesthenewsoyoudon'thaveto.
∙Thecontainerresolvesdependenciesbetweenobjectsitmanages.
Allthreepointsarerequiredandnecessaryifyou'retalkingaboutabasicIoCdefinition.Youhavetohaveacontainer,whichmanagesalltheIoCnessgoingon.DuetothenatureofIoC,thecontainerprettymuchhastodefinethelifecycleofobjects(Igenerallysayitmanagesthem).And,finally,thecontainerresolvesdependenciesbetweenservicesthatitcontrols.
Abasicexample
BeforeIgoanyfurther,averybasicexamplewillservetoillustratethebasicpoints.No,I'mnotgoingtousesomethingstupidlikeKissableorPeelablewhichwillleaveyoucompletelybewilderedastowhat'sgoingon.Instead,I'lluseverystrippeddownexamplesfrommyownwork.Thepointofthisistoshowexamplesinarealworldcontext,butalsotoshowmyownviewpointbetween"normal"JavaobjectsandIoCobjects,whichIwillgenerallycallservices.
SoimagineinmycodeIhaveabunchofservicesdefinedlikethis:
∙AnIJobDispatcher.Thisthingdispatchesa"job"forexecution.Youcallthe'dispatch'methodandtheclasstakesofdispatching/executingtheindicatedjob.Theactualdispatchingmayhappenremotelyormaybejustforwardedtoathreadpoolinsidetheprocess.Theprecisesemanticsdependonwhatyou'reusingthat'shiddenbehindtheIJobDispatcherinterface.
∙InthecodebelowwehaveaThreadPoolJobDispatcher.ItrequiresanIEventManagerandanICacheManagertogetitsjobdone.
∙Theeventmanagerhaseventspropogatedto,andinturnspitsoutjobs(whicharedispatchedtotheIJobDispatcher).TheThreadPoolJobDispatcherneedsahandleonthisguytoinformtheeventmanagerwhenajobhascompleted.
∙TheICacheManagermanagesinstancesofcaches.Thesemaybesomesortoffancydistributedcache,ormaybesomeglorifiedHashMapinsideofourprocess.Wedon'tcare,weonlyknowthattheThreadPoolJobDispatcherneedsacachetodoitsjob.
Sowehavethisdispatcherthing,whichneedsaneventmanagerandacachemanagertogetitsjobdone.It'slikelythattherewillbeonlyoneofeachofthese(e.g.moreoralessaSingleton),orattheleastaverysmallnumberofthem.Forexample,theremayperhapsbeaRemoteJobDispatcherandaThreadPoolJobDispatcherinsideofaprocess.Buttherewon'tbetensorhundredsofthem.Infactyoucouldsayforagivenkindofservice,therewillgenerallybeasmallnumberofthemupandaboutintheprocess.
OK,sogiventheabove,let'sshowanoutlineoftheThreadPoolJobDispatcher:
publicclassThreadPoolJobDispatcherimplementsIJobDispatcher{
publicThreadPoolJobDispatcher(IEventManagereventManager_,ICacheManagercacheMan_)
{
//Initializethyself!
}
publicvoiddispatch(Jobjob_)
{
//Dispatchit!
}
}
TheabovecodeshowstheoutlineoftheThreadPoolJobDispatcher.Asmentionedinthebulletlistabove,theThreadPoolJobDispatcherneedsanIEventManagerandanICacheManagertogetitsjobdone;inthecode,weseethatitgetstheseviaaconstructor.Thiscouldalsobedoneviasetters,whicharecalledoncetoinitializethejobdispatcher,inwhichcaseyou'dprobablyhaveanemptyconstructor.
UsingtheexamplewithoutIoC
Inpre-IoCdays,youwouldlikelyeitherhaveabunchofsingletonsrepresentingthesebeasties,orperhapsusealookupmechanismlikeJNDI.Onthesingletonside,ImightcreatemyThreadPoolJobDispatcherlikethis:
IJobDispatchertpDispatcher=newThreadPoolJobDispatcher(DefaultEventManager.instance(),
DumbMapCacheManager.instance());
Prettystraightforward,solongasyouknowthatyouactuallywantaDefaultEventManagerandaDumbMapCacheManagerandyoudon'tmindinvokingtheevilSingletondemon.
Alookupversionmightlooklike:
IJobDispatchertpDispatcher=newThreadPoolJobDispatcher((IEventManager)context.lookup("eventManager"),
(ICacheManager)context.lookup("cacheManager"));
or,perhaps,thejobdispatcherwilltakecareoflookuponitsonitsown:
publicclassThreadPoolJobDispatcherimplementsIJobDispatcher{
publicThreadPoolJobDispatcher(
{
_eventManager=(IEventManager)context.lookup("eventManager");
_cacheManager=(ICacheManager)context.lookup("cacheManager");
}
}
UsingtheexamplewithIoC
Thenon-IoCversionswilllookprettyfamiliartomostpeople.ButasallofthevariousIoCsiteswilltellyou,thesenono-IoCsolutionshavesomeproblems:
∙Singletonsareevil.Iwon'tgointowhy,youshouldalreadyknowwhy:
-).Frommyperspective,thebigproblemisthatyougettiedtoanimplementationclass,andyoucanonlyhaveoneofthem.WhatifIwanttochangemyThreadPoolJobDispatcherintotheRemoteJobDispatcher?
I'vegottostarthuntingdownsingletonreferences.Worse-whatifIsometimeswantoneandsometimestheother?
∙Toreinforcetheabove-ifyou'reusinginterfacestoallowthepossibilityofmultipleimplementations,theproblemof"whichone?
"comesupoften.WhichconcreteimplementationdoIneedhere,andhowdoIgetit?
∙Lookupstieyoutothelookupmechanism.WhenyouuseJNDI,orwhatever,yougettiedintothatimplementationinmanyplacesinyourcode.Inpracticethisisn'tallthatbad,butitcanmakeunittestingmoredifficult.
∙Withlookups,yougetmagicstrings/identifiersspreadthroughyourcode.Wheneveryoudolookups,youneedtolookupusingsomesortofkey,usuallyaString.Theselookupshaveatendencytospreadthroughyourcode,meaningyouhavemagicstringseverywhere,oroftenagiantclasscontainingStringconstants.
IoCcontainersgetaroundtheseproblemsbydoingtwothingsforyou:
1.Thecontainerisinchargeofcreatingobjects.Itdoesthenewsoyoudon'thaveto.
2.Thecontainerisinchargeofresolvingdependenciesforyou
Here'spsuedo-codeforhowanIoCsolutionwouldwork(note:
thisisveryverysparsepseudocode!
):
IoCContainercontainer=newIoCContainer();
container.register(DumbMapCacheManager);
container.register(DefaultEventManager);
container.register(ThreadPoolJobDispatcher);
IJobDispatcherdispatcher=container.getMe(IJobDispatcher);
What'shappeninghereisthefollowing:
∙Youcreatethecontainer.
∙Youregistereachofyourservices.Thedetailsofthisvarywildlyfromimplementationtoimplementation.
∙Yougetareferencetosomecontainermanagedobjectyouneedfromthecontainer.Thecontainertakescareofinstantiatingitforyou(ifithasn'talready),resolvingdependencies,andfinallyreturningtheproperreference.
Underthecovers,somethinglikethefollowingwillhappen(detailswillvaryfromimplementationtoimplementation-moreonthatlater!
):
1.Usingourexample,theabovepsuedo-codewillseethattheuserwantsadispatcher.
2.Thecontainerwillseethatithasregistereddispatcher(ThreadPoolJobDispatcher).
3.Thecontainerwillseethatithasn'tcreatedajobdispatcheryet.ItwillfurtherseethatthisThreadPoolJobDispatcherclassneedsareferencetoaDumbMapCacheManagerandDefaultEventManager.
4.Becauseofthepreviouspoint,itwillrecursivelydopoints1-3fortheacachemanagerandaneventmanager.
5.Oncethecontainerhasthosereferences,itwillinjectreferencestothemintotheThreadJobDispatcher.Thiswillbedoneeitherthroughaconstructororappropriatesetters.
Inlessdetailedlanguage,thecontainercreatestheDumbMapCacheManagerandDefaultEventManagerforyou,thencreateaThreadPoolJobDispatcherforyouwiththosereferencesinjectedintoit.
Whocares?
Anumberofpeoplewilllookattheabovecodeandsay"Whocares?
What'sthebigdeal?
".Well,asamatteroffact,usingIoCisn'tallthatbigofadeal.It'shardlywhatI'dcallavitalpieceofsoftwareinfrastructure,andyoucangetalongjustfinewithoutit.
ButwhatIoCdoesgiveyouisagreatdealofconvenience.Inpractice,whenyou'recodingwithinanIoCcontainer,youdon'tcarehowservicesarecreatedorworryabouthowtogetreferencestotheonesyouneed.It'stakencareofforyou.Onceyouhaveafairlystablecodebase,ifyouhappentoneedareferencetoanewserviceit'susuallyamatterofaddinganewconstructorargumentorsettermethod,with(hopefully!
)littleo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Inversion of Control Containers