研磨设计模式之 工厂方法模式25198.docx
研磨设计模式之 工厂方法模式-1 做Java一晃就十年了,最近手痒痒,也决定跟随一下潮流,整个博客,写点东西,就算对自己的知识进行一个梳理和总结,也跟朋友们交流交流,希望能坚持下去。 先写写设计模式方面的内容吧,就是GoF的23个模式,先从大家最熟悉的工厂方法模式开始,这个最简单,明白的人多,看看是否能写出点跟别人不一样的东西,欢迎大家来热烈讨论,提出建议或意见,并进行批评指正,一概虚心接受,在此先谢过了! 另外,大家也可以说说最想看到哪个模式,那我就先写它,呵呵,大家感兴趣,我才会有动力写下去!好了,言归正传,Now Go!工厂方法模式(Factory Method)1 场景景问题1.1 导出数数据的应应用框架架 考虑这这样一个个实际应应用:实实现一个个导出数数据的应应用框架架,来让让客户选选择数据据的导出出方式,并并真正执执行数据据导出。 在一些实际的企业应用中,一个公司的系统往往分散在很多个不同的地方运行,比如各个分公司或者是门市点,公司没有建立全公司专网的实力,但是又不愿意让业务数据实时的在广域网上传递,一个是考虑数据安全的问题,一个是运行速度的问题。 这种系统通常会有一个折中的方案,那就是各个分公司内运行系统的时候是独立的,是在自己分公司的局域网内运行。然后在每天业务结束的时候,各个分公司会导出自己的业务数据,然后把业务数据打包通过网络传送给总公司,或是专人把数据送到总公司,然后由总公司进行数据导入和核算。 通常这种系统,在导出数据上,会有一些约定的方式,比如导出成:文本格式、数据库备份形式、Excel格式、Xml格式等等。 现在就来考虑实现这样一个应用框架。在继续之前,先来了解一些关于框架的知识。1.2 框架的的基础知知识(1):框框架是什什么 简单点点说:框框架就是是能完成成一定功功能的半半成品软软件。 就就其本质质而言,框框架是一一个软件件,而且且是一个个半成品品的软件件。所谓谓半成品品,就是是还不能能完全实实现用户户需要的的功能,框框架只是是实现用用户需要要的功能能的一部部分,还还需要进进一步加加工,才才能成为为一个满满足用户户需要的的、完整整的软件件。因此此框架级级的软件件,它的的主要客客户是开开发人员员,而不不是最终终用户。 有些朋友会想,既然框架只是个半成品,那何必要去学习和使用框架呢?学习成本也不算小,那就是因为框架能完成一定的功能,也就是这“框架已经完成的一定的功能”在吸引着开发人员,让大家投入去学习和使用框架。(2):框框架能干干什么 能完完成一定定功能,加加快应用用开发进进度 由于框框架完成成了一定定的功能能,而且且通常是是一些基基础的、有有难度的的、通用用的功能能,这就就避免我我们在应应用开发发的时候候完全从从头开始始,而是是在框架架已有的的功能之之上继续续开发,也也就是说说会复用用框架的的功能,从从而加快快应用的的开发进进度。 给我我们一个个精良的的程序架架构 框架定定义了应应用的整整体结构构,包括括类和对对象的分分割,各各部分的的主要责责任,类类和对象象怎么协协作,以以及控制制流程等等等。现现在Jaava界界大多数数流行的的框架,大大都出自自大师手手笔,设设计都很很精良。基基于这样样的框架架来开发发,一般般会遵循循框架已已经规划划好的结结构来进进行开发发,从而而让我们们开发的的应用程程序的结结构也相相对变得得精良了了。(3):对对框架的的理解 基于于框架来来开发,事事情还是是那些事事情,只只是看谁谁做的问问题 对于应应用程序序和框架架的关系系,可以以用一个个图来简简单描述述一下,如如图1所所示: 图1 应用程程序和框框架的简简单关系系示意图图 如果没没有框架架,那么么客户要要求的所所有功能能都由开开发人员员自己来来开发,没没问题,同同样可以以实现用用户要求求的功能能,只是是开发人人员的工工作多点点。 如果有有了框架架,框架架本身完完成了一一定的功功能,那那么框架架已有的的功能,开开发人员员就可以以不做了了,开发发人员只只需要完完成框架架没有的的功能,最最后同样样是完成成客户要要求的所所有功能能,但是是开发人人员的工工作就减减少了。 也就是说,基于框架来开发,软件要完成的功能并没有变化,还是客户要求的所有功能,也就是“事情还是那些事情”的意思。但是有了框架过后,框架完成了一部分功能,然后开发人员再完成一部分功能,最后由框架和开发人员合起来完成了整个软件的功能,也就是看这些功能“由谁做”的问题。 基于于框架开开发,可可以不去去做框架架所做的的事情,但但是应该该明白框框架在干干什么,以以及框架架是如何何实现相相应功能能的 事实上上,在实实际开发发中,应应用程序序和框架架的关系系,通常常都不会会如上面面讲述的的那样,分分得那么么清楚,更更为普遍遍的是相相互交互互的,也也就是应应用程序序做一部部分工作作,然后后框架做做一部分分工作,然然后应用用程序再再做一部部分工作作,然后后框架再再做一部部分工作作,如此此交错,最最后由应应用程序序和框架架组合起起来完成成用户的的功能要要求。 也用用个图来来说明,如如图2所所示: 图22 应应用程序序和框架架的关系系示意图图 如果把把这个由由应用程程序和框框架组合合在一起起构成的的矩形,当当作最后后完成的的软件。试试想一下下,如果果你不懂懂框架在在干什么么的话,相相当于框框架对你你来讲是是个黑盒盒,也就就是相当当于在上上面图22中,去去掉框架架的两块块,会发发现什么么?没错错,剩下下的应用用程序是是支离破破碎的,是是相互分分隔开来来的。 这会会导致一一个非常常致命的的问题,整整个应用用是如何何运转起起来的,你你是不清清楚的,也也就是说说对你而而言,项项目已经经失控了了,从项项目管理理的角度度来讲,这这是很危危险的。 因此,在基于框架开发的时候,虽然我们可以不去做框架所做的事情,但是应该搞明白框架在干什么,如果条件许可的话,还应该搞清楚框架是如何实现相应功能的,至少应该把大致的实现思路和实现步骤搞清楚,这样我们才能整体的掌控整个项目,才能尽量减少出现项目失控的情况。(4):框框架和设设计模式式的关系系 设设计模式式比框架架更抽象象 框架架已经是是实现出出来的软软件了,虽虽然只是是个半成成品的软软件,但但毕竟是是已经实实现出来来的了。而而设计模模式的重重心还在在于解决决问题的的方案上上,也就就是还停停留在思思想的层层面。因因此设计计模式比比框架更更为抽象象。 设设计模式式是比框框架更小小的体系系结构元元素 如如上所述述,框架架是已经经实现出出来的软软件,并并实现了了一系列列的功能能,因此此一个框框架,通通常会包包含多个个设计模模式的应应用。 框架比比设计模模式更加加特例化化 框架架是完成成一定功功能的半半成品软软件,也也就是说说,框架架的目的的很明确确,就是是要解决决某一个个领域的的某些问问题,那那是很具具体的功功能,不不同的领领域实现现出来的的框架是是不一样样的。 而而设计模模式还停停留在思思想的层层面,在在不同的的领域都都可以应应用,只只要相应应的问题题适合用用某个设设计模式式来解决决。因此此框架总总是针对对特定领领域的,而而设计模模式更加加注重从从思想上上,从方方法上来来解决问问题,更更加通用用化。1.3 有何问问题 分分析上面面要实现现的应用用框架,不不管用户户选择什什么样的的导出格格式,最最后导出出的都是是一个文文件,而而且系统统并不知知道究竟竟要导出出成为什什么样的的文件,因因此应该该有一个个统一的的接口,来来描述系系统最后后生成的的对象,并并操作输输出的文文件。 先把导导出的文文件对象象的接口口定义出出来,示示例代码码如下: /* * 导出出的文件件对象的的接口 */publiic iinteerfaace ExpporttFilleAppi /* * 导导出内容容成为文文件 * parram datta 示示意:需需要保存存的数据据 * retturnn 是否否导出成成功 */ ppubllic boooleaan eexpoort(Strringg daata); 对于实实现导出出数据的的业务功功能对象象,它应应该根据据需要来来创建相相应的EExpoortFFileeApii的实现现对象,因因为特定定的ExxporrtFiileAApi的的实现是是与具体体的业务务相关的的。但是是对于实实现导出出数据的的业务功功能对象象而言,它它并不知知道应该该创建哪哪一个EExpoortFFileeApii的实现现对象,也也不知道道如何创创建。 也就就是说:对于实实现导出出数据的的业务功功能对象象,它需需要创建建ExpporttFilleAppi的具具体实例例对象,但但是它只只知道EExpoortFFileeApii接口,而而不知道道其具体体的实现现。那该该怎么办办呢?研磨设计模模式之 工厂方方法模式式-2 2 解解决方案案2.1 工厂方方法模式式来解决决 用来解解决上述述问题的的一个合合理的解解决方案案就是工工厂方法法模式。那那么什么么是工厂厂方法模模式呢?(1)工工厂方法法模式定定义 定义一一个用于于创建对对象的接接口,让让子类决决定实例例化哪一一个类,FFacttoryy Meethood使一一个类的的实例化化延迟到到其子类类。 (2)应用用工厂方方法模式式来解决决的思路路 仔仔细分析析上面的的问题,事事实上在在实现导导出数据据的业务务功能对对象里面面,根本本就不知知道究竟竟要使用用哪一种种导出文文件的格格式,因因此这个个对象本本就不应应该和具具体的导导出文件件的对象象耦合在在一起,它它只需要要面向导导出的文文件对象象的接口口就好了了。 但是这这样一来来,又有有新的问问题产生生了:接接口是不不能直接接使用的的,需要要使用具具体的接接口实现现对象的的实例。 这不是自相矛盾吗?要求面向接口,不让和具体的实现耦合,但是又需要创建接口的具体实现对象的实例。怎么解决这个矛盾呢? 工厂方法模式的解决思路很有意思,那就是不解决,采取无为而治的方式:不是需要接口对象吗,那就定义一个方法来创建;可是事实上它自己是不知道如何创建这个接口对象的,没有关系,那就定义成抽象方法就好了,自己实现不了,那就让子类来实现,这样这个对象本身就可以只是面向接口编程,而无需关心到底如何创建接口对象了。2.2 模式结结构和说说明 工厂方方法模式式的结构构如图33所示: 图3 工厂厂方法模模式结构构示意图图Produuct: 定定义工厂厂方法所所创建的的对象的的接口,也也就是实实际需要要使用的的对象的的接口。ConcreteProduct: 具体的Product接口的实现对象。Creator: 创建器,声明工厂方法,工厂方法通常会返回一个Product类型的实例对象,而且多是抽象方法。也可以在Creator里面提供工厂方法的默认实现,让工厂方法返回一个缺省的Product类型的实例对象。ConcreteCreator: 具体的创建器对象,覆盖实现Creator定义的工厂方法,返回具体的Product实例。2.3 工厂方方法模式式示例代代码(1)先看看看Prroduuct的的定义,示示例代码码如下:/* * 工厂厂方法所所创建的的对象的的接口 */publiic iinteerfaace Prooducct /可以以定义PProdductt的属性性和方法法(2)再看看看具体体的Prroduuct的的实现对对象,示示例代码码如下: /* * 具体体的Prroduuct对对象 */publiic cclasss CConccrettePrroduuct impplemmentts PProdductt /实现现Prooducct要求求的方法法(3)接下下来看看看创建器器的定义义,示例例代码如如下: /* * 创建建器,声声明工厂厂方法 */publiic aabsttracct cclasss CCreaatorr /* * 创创建Prroduuct的的工厂方方法 * retturnn Prroduuct对对象 */ pprottectted absstraact Prooducct ffacttoryyMetthodd(); /* * 示示意方法法,实现现某些功功能的方方法 */ ppubllic voiid ssomeeOpeerattionn() /通常常在这些些方法实实现中,需需要调用用工厂方方法来获获取Prroduuct对对象 PProdductt prroduuct = ffacttoryyMetthodd(); (4)再看看看具体体的创建建器实现现对象,示示例代码码如下: /* * 具体体的创建建器实现现对象 */publiic cclasss CConccretteCrreattor exttendds CCreaatorr pprottectted Prooducct ffacttoryyMetthodd() /重定定义工厂厂方法,返返回一个个具体的的Prooducct对象象 rretuurn neww CooncrreteeProoducct(); 2.4 使用工工厂方法法模式来来实现示示例 要使用用工厂方方法模式式来实现现示例,先先来按照照工厂方方法模式式的结构构,对应应出哪些些是被创创建的PProdductt,哪些些是Crreattor。分分析要求求实现的的功能,导导出的文文件对象象接口EExpoortFFileeApii就相当当于是PProdductt,而用用来实现现导出数数据的业业务功能能对象就就相当于于Creeatoor。把把Prooducct和CCreaatorr分开过过后,就就可以分分别来实实现它们们了。 使用用工厂模模式来实实现示例例的程序序结构如如图4所所示: 图图4 使用工工厂模式式来实现现示例的的程序结结构示意意图 下下面一起起来看看看代码实实现。(11)导出出的文件件对象接接口ExxporrtFiileAApi的的实现没没有变化化,这里里就不去去赘述了了(2)接接下来看看看接口口ExpporttFilleAppi的实实现,为为了示例例简单,只只实现导导出文本本文件格格式和数数据库备备份文件件两种。先先看看导导出文本本文件格格式的实实现,示示例代码码如下: /* * 导出出成文本本文件格格式的对对象 */publiic cclasss EExpoortTTxtFFilee immpleemennts ExpporttFilleAppi ppubllic boooleaan eexpoort(Strringg daata) /简单单示意一一下,这这里需要要操作文文件 SSysttem.outt.prrinttln("导出出数据""+daata+"到文文本文件件"); rretuurn truue; 再看看导出出成数据据库备份份文件形形式的对对象的实实现,示示例代码码如下: /* * 导出出成数据据库备份份文件形形式的对对象 */publiic cclasss EExpoortDDB iimpllemeentss ExxporrtFiileAApi ppubllic boooleaan eexpoort(Strringg daata) /简单单示意一一下,这这里需要要操作数数据库和和文件 SSysttem.outt.prrinttln("导出出数据""+daata+"到数数据库备备份文件件"); rretuurn truue; (3)Crreattor这这边的实实现,首首先看看看ExpporttOpeeratte的实实现,示示例代码码如下: /* * 实现现导出数数据的业业务功能能对象 */publiic aabsttracct cclasss EExpoortOOperratee /* * 导导出文件件 * parram datta 需需要保存存的数据据 * retturnn 是否否成功导导出文件件 */ ppubllic boooleaan eexpoort(Strringg daata) /使用用工厂方方法 EExpoortFFileeApii appi = faactooryMMethhod(); rretuurn apii.exxporrt(ddataa); /* * 工工厂方法法,创建建导出的的文件对对象的接接口对象象 * retturnn 导出出的文件件对象的的接口对对象 */ pprottectted absstraact ExpporttFilleAppi ffacttoryyMetthodd();(4)加入入了两个个Creeatoor实现现,先看看看创建建导出成成文本文文件格式式的对象象,示例例代码如如下: /* * 具体体的创建建器实现现对象,实实现创建建导出成成文本文文件格式式的对象象 */publiic cclasss EExpoortTTxtFFileeOpeeratte eexteendss ExxporrtOpperaate pprottectted ExpporttFilleAppi ffacttoryyMetthodd() /创建建导出成成文本文文件格式式的对象象 rretuurn neww ExxporrtTxxtFiile(); 再看看创建建导出成成数据库库备份文文件形式式的对象象,示例例代码如如下: /* * 具体体的创建建器实现现对象,实实现创建建导出成成数据库库备份文文件形式式的对象象 */publiic cclasss EExpoortDDBOpperaate exttendds EExpoortOOperratee pprottectted ExpporttFilleAppi ffacttoryyMetthodd() /创建建导出成成数据库库备份文文件形式式的对象象 rretuurn neww ExxporrtDBB(); (5)客户户端直接接创建需需要使用用的Crreattor对对象,然然后调用用相应的的功能方方法,示示例代码码如下: publiic cclasss CClieent ppubllic staaticc vooid maiin(SStriing aargss) /创建建需要使使用的CCreaatorr对象 EExpoortOOperratee opperaate = nnew ExpporttDBOOperratee(); /调用用输出数数据的功功能方法法 ooperratee.exxporrt(""测试数数据"); 运行结果如如下: 导出数据测测试数据据到数据据库备份份文件 你还还可以修修改客户户端neew的对对象,切切换成其其它的实实现对象象,试试试看会发发生什么么。看来来应用工工厂方法法模式是是很简单单的,对对吧。研磨设计模模式之 工厂方方法模式式-33 模式式讲解3.1 认识工工厂方法法模式(1)模式式的功能能 工工厂方法法的主要要功能是是让父类类在不知知道具体体实现的的情况下下,完成成自身的的功能调调用,而而具体的的实现延延迟到子子类来实实现。 这样样在设计计的时候候,不用用去考虑虑具体的的实现,需需要某个个对象,把把它通过过工厂方方法返回回就好了了,在使使用这些些对象实实现功能能的时候候还是通通过接口口来操作作,这非非常类似似于IooC/DDI的思思想,这这个在后后面给大大家稍详详细点介介绍一下下。(2)实现现成抽象象类 工厂方方法的实实现中,通通常父类类会是一一个抽象象类,里里面包含含创建所所需对象象的抽象象方法,这这些抽象象方法就就是工厂厂方法。 这里要注意一个问题,子类在实现这些抽象方法的时候,通常并不是真的由子类来实现具体的功能,而是在子类的方法里面做选择,选择具体的产品实现对象。 父类里面,通常会有使用这些产品对象来实现一定的功能的方法,而且这些方法所实现的功能通常都是公共的功能,不管子类选择了何种具体的产品实现,这些方法的功能总是能正确执行。(3)实现现成具体体的类 当然然也可以以把父类类实现成成为一个个具体的的类,这这种情况况下,通通常是在在父类中中提供获获取所需需对象的的默认实实现方法法,这样样就算没没有具体体的子类类,也能能够运行行。 通常这这种情况况还是需需要具体体的子类类来决定定具体要要如何创创建父类类所需要要的对象象。也把把这种情情况称为为工厂方方法为子子类提供供了挂钩钩,通过过工厂方方法,可可以让子子类对象象来覆盖盖父类的的实现,从从而提供供更好的的灵活性性。(4)工厂厂方法的的参数和和返回 工厂厂方法的的实现中中,可能能需要参参数,以以便决定定到底选选用哪一一种具体体的实现现。也就就是说通通过在抽抽象方法法里面传传递参数数,在子子类实现现的时候候根据参参数进行行选择,看看看究竟竟应该创创建哪一一个具体体的实现现对象。 一般工厂方法返回的是被创建对象的接口对象,当然也可以是抽象类或者一个具体的类的实例。(5)谁来来使用工工厂方法法创建的的对象 这里里首先要要搞明白白一件事事情,就就是谁在在使用工工厂方法法创建的的对象? 事事实上,在在工厂方方法模式式里面,应应该是CCreaatorr中的其其它方法法在使用用工厂方方法创建建的对象象,虽然然也可以以把工厂厂方法创创建的对对象直接接提供给给Creeatoor外部部使用,但但工厂方方法模式式的本意意,是由由Creeatoor对象象内部的的方法来来使用工工厂方法法创建的的对象,也也就是说说,工厂厂方法一一般不提提供给CCreaatorr外部使使用。 客户户端应该该是使用用Creeatoor对象象,或者者是使用用由Crreattor创创建出来来的对象象。对于于客户端端使用CCreaatorr对象,这这个时候候工厂方方法创建建的对象象,是CCreaatorr中的某某些方法法使用。对对于使用用那些由由Creeatoor创建建出来的的对象,这这个时候候工厂方方法创建建的对象象,是构构成客户户端需要要的对象象的一部部分。分分别举例例来说明明。 客户端端使用CCreaatorr对象的的情况 比如如前面的的示例,对对于“实实现导出出数据的的业务功功能对象象”的类类ExpporttOpeeratte,它它有一个个expportt的方法法,在这这个方法法里面,需需要使用用具体的的“导出出的文件件对象的的接口对对象” ExpporttFilleAppi,而而ExpporttOpeeratte是不不知道具具体的EExpoortFFileeApii实现的的,那么么怎么做做的呢?就是定定义了一一个工厂厂方法,用用来返回回ExpporttFilleAppi的对对象,然然后exxporrt方法法会使用用这个工工厂方法法来获取取它所需需要的对对象,然然后执行行功能。 这个时候的客户端是怎么做的呢?这个时候客户端主要就是使用这个ExportOperate的实例来完成它想要完成的功能,也就是客户端使用Creator对象的情况,简单描述这种情况下的代码结构如下: /* * 客户户端使用用Creeatoor对象象的情况况下,CCreaatorr的基本本实现结结构 */publiic aabsttracct cclasss CCreaatorr /* * 工工厂方法法,一般般不对外外 * retturnn 创建建的产品品对象 */ pprottectted absstraact Prooducct ffacttoryyMetthodd(); /* * 提提供给外外部使用用的方法法, * 客客户端一一般使用用Creeatoor提供供的这些些方法来来完成所所需要的的功能 */ ppubllic voiid ssomeeOpeerattionn() /在这这里使用用工厂方方法 PProdductt p = ffacttoryyMetthodd(); 客户端使使用由CCreaatorr创建出出来的对对象 另外一一种是由由Creeatoor向客客户端返返回由“工工厂方法法创建的的对象”来来构建的的对象,这这个时候候工厂方方法创建建的对象象,是构构成客户户端需要要的对象象的一部部分。简简单描述述这种情情况下的的代码结结构如下下: /* * 客户户端使用用Creeatoor来创创建客户户端需要要的对象象的情况况下,CCreaatorr的基本本实现结结构 */publiic aabsttracct cclasss CCreaatorr /* * 工工厂方法法,一般般不对外外,创建建一个部部件对象象 * retturnn 创建建的产品品对象,一一般是另另一个产产品对象象的部件件 */ pprottectted absstraact Prooducct1 facctorryMeethood1(); /* * 工工厂方法法,一般般不对外外,创建建一个部部件对象象 * retturnn 创建建的产品品对象,一一般是另另一个产产品对象象的部件件 */ pprottectted absstraact Prooducct2 facctorryMeethood2(); /* * 创创建客户户端需要要的对象象,客户户端主要要使用产产品对象象来完成成所需要要的功能能 * retturnn 客户户端需要要的对象象 */ ppubllic Prooducct ccreaatePProdductt() /在这这里使用用工厂方方法,得得到客户户端所需需对象的的部件对对象 PProdductt1 pp1 = faactooryMMethhod11(); PProdductt2 pp2 = faactooryMMethhod22(); /工厂厂方法创创建的对对象是创创建客户户端对象象所需要要的 PProdductt p = nnew ConncreetePProdductt(); pp.seetPrroduuct11(p11); pp.seetPrroduuct22(p22); rretuurn p; 小结一一下:在在工厂方方法模式式里面,客客户端要要么使用用Creeatoor对象象,要么么使用CCreaatorr创建的的对象,一一般客户户端不直直接使用用工厂方方法。当当然也可可以直接接把工厂厂方法暴暴露给客客户端操操作,但但是一般般不这么么做。(6)工厂厂方法模模式的调调用顺序序示意图图 由由于客户户端使用用Creeatoor对象象有两种种典型的的情况,因因此调用用的顺序序示意图图也分做做两种情情况,先先看看客客户端使使用由CCreaatorr创建出出来的对对象情况况的调用用顺序示示意图,如如图5所所示: 图5 客户户端使用用由Crreattor创创建出来来的对象象的调用用顺序示示意图接下来看看看客户端端使用CCreaatorr对象时时候的调调用顺序序示意图图,如图图6所示示: 图6 客户户端使用用Creeatoor对象象的调用用顺序示示意图研磨设计模模式之 工厂方方法模式式-43.2 工厂方方法模式式与IooC/DDI IoCInnverrsioon oof CConttroll 控控制反转转 DIIDDepeendeencyy Innjecctioon 依赖赖注入1:如何理理解IooC/DDI 要想理理解上面面两个概概念,就就必须搞搞清楚如如下的问问题:· 参与者都有有谁? · 依赖:谁依依赖于谁谁?为什什么需要要依赖? · 注入:谁注注入于谁谁?到底底注入什什么? · 控制反转:谁控制制谁?控控制什么么?为何何叫反转转(有反反转就应应该有正正转了)? · 依赖注入和和控制反反转是同同一概念念吗? 下面就就来简要要的回答答一下上上述问题题,把这这些问题题搞明白白了,IIoC/DI也也就明白白了。(11)参与与者都有有谁: 一般有有三方参参与者,一一个是某某个对象象;一个个是IooC/DDI的容容器;另另一个是是某个对对象的外外部资源源。 又要名名词解释释一下,某某个对象象指的就就是任意意的、普普通的JJavaa对象; IooC/DDI的容容器简单单点说就就是指用用来实现现IoCC/DII功能的的一个框框架程序序;对象象的外部部资源指指的就是是对象需需要的,但但是是从从对象外外部获取取的,都都统称资资源,比比如:对对象需要要的其它它对象、或或者是对对象需要要的文件件资源等等等。(22)谁依依赖于谁谁: 当然是是某个对对象依赖赖于IooC/DDI的容容器(33)为什什么需要要依赖: 对象需需要IooC/DDI的容容器来提提供对象象需要的的外部资资源(44)谁注注入于谁谁: 很明显显是IooC/DDI的容容器 注注入 某某个对象象(5)到到底注入入什么: 就是注注入某个个对象所所需要的的外部资资源(66)谁控控制谁: 当然是是IoCC/DII的容器器来控制制对象了了(7)控控制什么么: 主要是是控制对对象实例例的创建建(8)为为何叫反反转: 反转是是相对于于正向而而言的,那那么什么么算是正正向的呢呢?考虑虑一下常常规情况况下的应应用程序序,如果果要在AA里面使使用C,你你会怎么么做呢?当然是是直接去去创建CC的对象象,也就就是说,是是在A类类中主动动去获取取所需要要的外部部资源CC,这种种情况被被称为正正向的。那那么什么么是反向向呢?就就是A类类不再主主动去获获取C,而而是被动动等待,等等待IooC/DDI的容容器获取取一个CC的实例例,然后后反向的的注入到到A类中中。 用图例例来说明明一下,先先看没有有IoCC/DII的时候候,常规规的A类类使用CC类的示示意图,如如图7所所示: 图7 常规规A使用用C示意意图当有了IooC/DDI的容容器后,AA类不再再主动去去创建CC了,如如图8所所示: 图图8 A类不不再主动动创建CC而是被动等等待,等等待IooC/DDI的容容器获取取一个CC的实例例,然后后反向的的注入到到A类中中,如图图9所示示: 图9 有IIoC/DI容容器后程程序结构构示意图图(9)依赖赖注入和和控制反反转是同同一概念念吗? 根据据上面的的讲述,应应该能看看出来,依依赖注入入和控制制反转是是对同一一件事情情的不同同描述,从从某个方方面讲,就就是它们们描述的的角度不不同。依依赖注入入是从应应用程序序的角度度在描述述,可以以把依赖赖注入描描述完整整点:应应用程序序依赖容容