控制反转:修订间差异
无编辑摘要 |
|||
(未显示15个用户的22个中间版本) | |||
第1行: | 第1行: | ||
{{专家|计算机科学}} |
|||
{{ |
{{No footnotes|time=2021-03-22T10:18:59+00:00}} |
||
{{noteTA|G1=IT}} |
{{noteTA|G1=IT}} |
||
'''控制反转''' |
'''控制反转'''({{lang-en|Inversion of Control}},缩写为'''IoC'''),是[[面向对象编程]]中的一种设计原则,可以用来减低计算机代码之间的[[耦合度 (計算機科學)|耦合度]]。其中最常见的方式叫做'''依赖注入'''(Dependency Injection,简称'''DI'''),还有一种方式叫“依赖查找”(Dependency Lookup)。 |
||
== 起源 == |
== 起源 == |
||
早在2004年,[[Martin Fowler]]就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了,因为大多数应用程序都是由两个或是更多的类通过彼此的合作来实现 |
早在2004年,[[Martin Fowler]]就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了,因为大多数应用程序都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么这将导致代码高度[[耦合力 (計算機科學)|耦合]]并且难以维护和调试。 |
||
==技术描述== |
==技术描述== |
||
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式 |
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式地用 new 建立 B 的对象。 |
||
采用依赖注入技术之后,A的代码只需要定义一个 |
采用依赖注入技术之后,A 的代码只需要定义一个 private 的B对象,不需要直接 new 来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。 |
||
IoC也可以理解为把流程的控制从应用程序转移到框架之中。以前,应用程序掌握整个处理流程;现在,控制权转移到了框架,框架利用一个引擎驱动整个流程的执行,框架会以相应的形式提供一系列的扩展点,应用程序则通过定义扩展的方式实现对流程某个环节的定制,“框架Call应用”。基于MVC的web应用程序就是如此。 |
|||
==实现方法== |
==实现方法== |
||
第15行: | 第18行: | ||
===依赖注入=== |
===依赖注入=== |
||
{{Main | 依赖注入}} |
|||
依赖注入有如下实现方式: |
依赖注入有如下实现方式: |
||
* 基于接口。实现特定接口以供外部容器注入所依赖类型的对象。 |
* 基于接口。实现特定接口以供外部容器注入所依赖类型的对象。 |
||
第27行: | 第31行: | ||
=== C++ === |
=== C++ === |
||
* [http://code.google.com/p/pococapsule PocoCapsule IoC and DSM framework] LGPL开源的,支持完全非侵入C++的控制反转(IoC)及领域特定建模(DSM)容器 |
* [http://code.google.com/p/pococapsule PocoCapsule IoC and DSM framework] {{Wayback|url=http://code.google.com/p/pococapsule |date=20110424112934 }} LGPL开源的,支持完全非侵入C++的控制反转(IoC)及领域特定建模(DSM)容器 |
||
* [https://github.com/ybainier/Hypodermic hypodermic] MIT开源协议,Hypodermic是一个基于[[C++11]]开发的控制反转(IoC)容器,它为你的C++对象协作提供依赖注入。Hypodermic灵感来自著名的.NET IoC项目Autofac。 |
* [https://github.com/ybainier/Hypodermic hypodermic] {{Wayback|url=https://github.com/ybainier/Hypodermic |date=20201024191426 }} MIT开源协议,Hypodermic是一个基于[[C++11]]开发的控制反转(IoC)容器,它为你的C++对象协作提供依赖注入。Hypodermic灵感来自著名的.NET IoC项目Autofac。 |
||
=== Java === |
=== Java === |
||
使用[[Java|Java語言]]寫成的程式在控制反轉容器(''Inversion of Control Container'')裡應用了控制反轉{{ref_harvard|Fowler 2004|Martin 2004|none}}。軟體需要一個來自容器的物件,而容器自行建構物件和它的附屬物。 |
使用[[Java|Java語言]]寫成的程式在控制反轉容器(''Inversion of Control Container'')裡應用了控制反轉{{ref_harvard|Fowler 2004|Martin 2004|none}}。軟體需要一個來自容器的物件,而容器自行建構物件和它的附屬物。{{tsl|en|Art Technology Group||ATG}} 的 [[Dynamo 應用程式伺服器]]是第一個利用這途徑的環境之一,近來關於這些容器的例子包含了 [[HiveMind]]、[http://www.picocontainer.org PicoContainer] {{Wayback|url=http://www.picocontainer.org/ |date=20170218202955 }}、[[Spring Framework]](注意 Spring 是一個完整的企業平台,而非 IOC容器)、[[Apache Excalibur]]、[[Seasar]] 和 [http://www.dpml.net/metro/ DPML Metro]. |
||
=== .NET === |
=== .NET === |
||
* [http://www.ninject.org/ Ninject] |
* [http://www.ninject.org/ Ninject] {{Wayback|url=http://www.ninject.org/ |date=20210225040333 }} |
||
* [http://www.springframework.net/ Spring.NET] |
* [http://www.springframework.net/ Spring.NET] {{Wayback|url=http://www.springframework.net/ |date=20060402205922 }} |
||
* [http://objectbuilder.codeplex.com/ ObjectBuilder] |
* [http://objectbuilder.codeplex.com/ ObjectBuilder] {{Wayback|url=http://objectbuilder.codeplex.com/ |date=20180106155101 }} |
||
* [http://structuremap.sourceforge.net Structuremap]{{ |
* [http://structuremap.sourceforge.net Structuremap] {{Wayback|url=http://structuremap.sourceforge.net/ |date=20041124014224 }} |
||
* [https://web.archive.org/web/20060924095633/http://www.castleproject.org/index.php/Main_Page CastleProject] |
* [https://web.archive.org/web/20060924095633/http://www.castleproject.org/index.php/Main_Page CastleProject] |
||
* [http://www.seasar.org/en/dotnet/ Seasar] |
* [http://www.seasar.org/en/dotnet/ Seasar] {{Wayback|url=http://www.seasar.org/en/dotnet/ |date=20060725015434 }} |
||
* [https://autofac.org/ Autofac] {{Wayback|url=https://autofac.org/ |date=20210310011049 }} |
|||
* Autofac |
|||
* [https://code.msdn.microsoft.com/Dependency-Injection-in-11d54863/ Unity] {{Wayback|url=https://code.msdn.microsoft.com/Dependency-Injection-in-11d54863/ |date=20190604190348 }} |
|||
*MET |
|||
=== PHP === |
=== PHP === |
||
* [[Phalcon]] PHP |
* [[Phalcon]] PHP框架中应用了依赖注入:[http://docs.phalconphp.com/en/latest/reference/di.html DI in Phalcon] {{Wayback|url=http://docs.phalconphp.com/en/latest/reference/di.html |date=20160422133600 }} |
||
* [[Laravel]] PHP框架核心的服务容器支持依赖注入:[https://laravel.com/docs/container#automatic-injection Service Container] |
|||
==参考文档== |
==参考文档== |
||
第66行: | 第73行: | ||
| author= [[Martin Fowler]] |
| author= [[Martin Fowler]] |
||
| year= 2004 |
| year= 2004 |
||
| url |
| url= http://martinfowler.com/articles/injection.html |
||
| title= Inversion of Control Containers and the Dependency Injection Pattern |
| title= Inversion of Control Containers and the Dependency Injection Pattern |
||
| accessdate= 2005-11-15 |
| accessdate= 2005-11-15 |
||
| archive-date= 2020-05-30 |
|||
⚫ | |||
| archive-url= https://web.archive.org/web/20200530200224/https://martinfowler.com/articles/injection.html |
|||
| dead-url= no |
|||
⚫ | |||
#{{note_label|Mathew 2005|Mathew 2005|none}} {{cite web |
#{{note_label|Mathew 2005|Mathew 2005|none}} {{cite web |
||
| author= Sony Mathew |
| author= Sony Mathew |
||
| year= 2005 |
| year= 2005 |
||
| url |
| url= http://theserverside.com/articles/article.tss?l=IOCandEJB |
||
| title= Examining the Validity of Inversion of Control |
| title= Examining the Validity of Inversion of Control |
||
| accessdate= 2005-11-16 |
| accessdate= 2005-11-16 |
||
| archive-url= https://web.archive.org/web/20051129090356/http://www.theserverside.com/articles/article.tss?l=IOCandEJB |
|||
⚫ | |||
| archive-date= 2005-11-29 |
|||
| dead-url= yes |
|||
⚫ | |||
#{{note_label|DSM in IoC|DSM in IoC|none}} {{cite web |
#{{note_label|DSM in IoC|DSM in IoC|none}} {{cite web |
||
| author= Ke Jin |
| author= Ke Jin |
||
| year= 2007 |
| year= 2007 |
||
| url |
| url= http://www.theserverside.com/news/thread.tss?thread_id=47546 |
||
| title= Domain Specific Modeling (DSM) in IoC frameworks |
| title= Domain Specific Modeling (DSM) in IoC frameworks |
||
| accessdate= 2007-11-13 |
| accessdate= 2007-11-13 |
||
| archive-date= 2007-11-15 |
|||
⚫ | |||
| archive-url= https://web.archive.org/web/20071115185128/http://www.theserverside.com/news/thread.tss?thread_id=47546 |
|||
| dead-url= yes |
|||
⚫ | |||
⚫ | |||
==外部链接== |
==外部链接== |
||
*[https://web.archive.org/web/20060904143154/http://docs.codehaus.org/display/PICO/Inversion+of+Control Another description of IOC] |
*[https://web.archive.org/web/20060904143154/http://docs.codehaus.org/display/PICO/Inversion+of+Control Another description of IOC] |
||
*A list of "[http://java-source.net/open-source/containers Open Source Inversion of Control Containers]" |
*A list of "[http://java-source.net/open-source/containers Open Source Inversion of Control Containers] {{Wayback|url=http://java-source.net/open-source/containers |date=20200203162747 }}" |
||
*[https://web.archive.org/web/20061007203232/http://www.drrockit.com/space/Java/Simple+Spring+Demo A simple demo of Inversion of Control] (using [[Spring framework]]) |
*[https://web.archive.org/web/20061007203232/http://www.drrockit.com/space/Java/Simple+Spring+Demo A simple demo of Inversion of Control] (using [[Spring framework]]) |
||
*[http://www.martinfowler.com/articles/injection.html Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler] |
*[http://www.martinfowler.com/articles/injection.html Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler] {{Wayback|url=http://www.martinfowler.com/articles/injection.html |date=20200512234946 }} |
||
*[https://web.archive.org/web/20060916075212/http://needle.rubyforge.org/ Needle], a dependency injection (inversion of control) container for [http://www.ruby-lang.org Ruby] |
*[https://web.archive.org/web/20060916075212/http://needle.rubyforge.org/ Needle], a dependency injection (inversion of control) container for [http://www.ruby-lang.org Ruby] {{Wayback|url=http://www.ruby-lang.org/ |date=20200108175215 }} |
||
*[http://drip.tigris.org/ Drip IoC], a dependency injection (inversion of control) container for [http://www.php.net PHP4] |
*[http://drip.tigris.org/ Drip IoC] {{Wayback|url=http://drip.tigris.org/ |date=20110821041348 }}, a dependency injection (inversion of control) container for [http://www.php.net PHP4] {{Wayback|url=http://www.php.net/ |date=20110309031650 }} |
||
*[http://pycontainer.sourceforge.net/ PyContainer], a dependency injection (inversion of control) container for [http://www.python.org/ Python] |
*[http://pycontainer.sourceforge.net/ PyContainer] {{Wayback|url=http://pycontainer.sourceforge.net/ |date=20160403145228 }}, a dependency injection (inversion of control) container for [http://www.python.org/ Python] {{Wayback|url=http://www.python.org/ |date=20180417023815 }} |
||
*[http://sourceforge.net/projects/qtioccontainer Qt Ioc Container], a dependency injection (inversion of control) container for [http://en.wikipedia.org/wiki/C%2B%2B C++] |
*[http://sourceforge.net/projects/qtioccontainer Qt Ioc Container] {{Wayback|url=http://sourceforge.net/projects/qtioccontainer |date=20160411140253 }}, a dependency injection (inversion of control) container for [http://en.wikipedia.org/wiki/C%2B%2B C++] {{Wayback|url=http://en.wikipedia.org/wiki/C%2B%2B |date=20210320170541 }} |
||
*[https://web.archive.org/web/20061106061409/http://www.codeproject.com/cs/design/introducingcastle.asp Introducing Castle], explains the problems that Inversion of control containers try to solve (using [[Castle Project]]) |
*[https://web.archive.org/web/20061106061409/http://www.codeproject.com/cs/design/introducingcastle.asp Introducing Castle], explains the problems that Inversion of control containers try to solve (using [[Castle Project]]) |
||
*[http://code.google.com/p/pococapsule PocoCapsule] An open source IoC and DSM framework for C++ |
*[http://code.google.com/p/pococapsule PocoCapsule] {{Wayback|url=http://code.google.com/p/pococapsule |date=20110424112934 }} An open source IoC and DSM framework for C++ |
||
*[http://www.theserverside.com/news/thread.tss?thread_id=47546 Domain Specific Modeling (DSM) in IoC frameworks] |
*[http://www.theserverside.com/news/thread.tss?thread_id=47546 Domain Specific Modeling (DSM) in IoC frameworks] {{Wayback|url=http://www.theserverside.com/news/thread.tss?thread_id=47546 |date=20071115185128 }} |
||
== 參考文獻 == |
|||
⚫ | |||
{{软件设计模式}} |
{{软件设计模式}} |
||
⚫ | |||
[[Category:面向对象的程序设计]] |
[[Category:面向对象的程序设计]] |
||
[[Category:基于组件的软件工程]] |
[[Category:基于组件的软件工程]] |
||
[[Category:Java]] |
|||
[[Category:编程原则]] |
|||
[[Category:软件架构]] |
|||
⚫ |
2022年9月1日 (四) 06:01的最新版本
此條目需要精通或熟悉计算机科学的编者参与及协助编辑。 |
控制反转(英語:Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
起源
[编辑]早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了,因为大多数应用程序都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么这将导致代码高度耦合并且难以维护和调试。
技术描述
[编辑]Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式地用 new 建立 B 的对象。
采用依赖注入技术之后,A 的代码只需要定义一个 private 的B对象,不需要直接 new 来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
IoC也可以理解为把流程的控制从应用程序转移到框架之中。以前,应用程序掌握整个处理流程;现在,控制权转移到了框架,框架利用一个引擎驱动整个流程的执行,框架会以相应的形式提供一系列的扩展点,应用程序则通过定义扩展的方式实现对流程某个环节的定制,“框架Call应用”。基于MVC的web应用程序就是如此。
实现方法
[编辑]实现控制反转主要有两种方式:依赖注入和依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取相应类型的对象,获得依赖对象的时间也可以在代码中自由控制。
依赖注入
[编辑]依赖注入有如下实现方式:
- 基于接口。实现特定接口以供外部容器注入所依赖类型的对象。
- 基于 set 方法。实现特定属性的public set方法,来让外部容器调用传入所依赖类型的对象。
- 基於构造函数。实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。
- 基于注解。基于Java的注解功能,在私有变量前加“@Autowired”等注解,不需要显式的定义以上三种代码,便可以让外部容器传入对应的对象。该方案相当于定义了public的set方法,但是因为没有真正的set方法,从而不会为了实现依赖注入导致暴露了不该暴露的接口(因为set方法只想让容器访问来注入而并不希望其他依赖此类的对象访问)。
依赖查找
[编辑]依赖查找更加主动,在需要的时候通过调用框架提供的方法来获取对象,获取时需要提供相关的配置文件路径、key等信息来确定获取对象的状态
控制反转应用实例
[编辑]C++
[编辑]- PocoCapsule IoC and DSM framework (页面存档备份,存于互联网档案馆) LGPL开源的,支持完全非侵入C++的控制反转(IoC)及领域特定建模(DSM)容器
- hypodermic (页面存档备份,存于互联网档案馆) MIT开源协议,Hypodermic是一个基于C++11开发的控制反转(IoC)容器,它为你的C++对象协作提供依赖注入。Hypodermic灵感来自著名的.NET IoC项目Autofac。
Java
[编辑]使用Java語言寫成的程式在控制反轉容器(Inversion of Control Container)裡應用了控制反轉(Martin 2004)。軟體需要一個來自容器的物件,而容器自行建構物件和它的附屬物。ATG 的 Dynamo 應用程式伺服器是第一個利用這途徑的環境之一,近來關於這些容器的例子包含了 HiveMind、PicoContainer (页面存档备份,存于互联网档案馆)、Spring Framework(注意 Spring 是一個完整的企業平台,而非 IOC容器)、Apache Excalibur、Seasar 和 DPML Metro.
.NET
[编辑]- Ninject (页面存档备份,存于互联网档案馆)
- Spring.NET (页面存档备份,存于互联网档案馆)
- ObjectBuilder (页面存档备份,存于互联网档案馆)
- Structuremap (页面存档备份,存于互联网档案馆)
- CastleProject
- Seasar (页面存档备份,存于互联网档案馆)
- Autofac (页面存档备份,存于互联网档案馆)
- Unity (页面存档备份,存于互联网档案馆)
- MET
PHP
[编辑]- Phalcon PHP框架中应用了依赖注入:DI in Phalcon (页面存档备份,存于互联网档案馆)
- Laravel PHP框架核心的服务容器支持依赖注入:Service Container
参考文档
[编辑]- ^ Robert Cecil Martin. Agile Software Development: Principles, Patterns and Practices. Pearson Education. 2002. ISBN 978-0-13-597444-5.
- ^ Robert Cecil Martin. The Dependency Inversion Principle (PDF). [2005-11-15]. (原始内容 (PDF)存档于2004-12-21).
- ^ Martin Fowler. Inversion of Control Containers and the Dependency Injection Pattern. 2004 [2005-11-15]. (原始内容存档于2020-05-30).
- ^ Sony Mathew. Examining the Validity of Inversion of Control. 2005 [2005-11-16]. (原始内容存档于2005-11-29).
- ^ Ke Jin. Domain Specific Modeling (DSM) in IoC frameworks. 2007 [2007-11-13]. (原始内容存档于2007-11-15).
外部链接
[编辑]- Another description of IOC
- A list of "Open Source Inversion of Control Containers (页面存档备份,存于互联网档案馆)"
- A simple demo of Inversion of Control (using Spring framework)
- Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler (页面存档备份,存于互联网档案馆)
- Needle, a dependency injection (inversion of control) container for Ruby (页面存档备份,存于互联网档案馆)
- Drip IoC (页面存档备份,存于互联网档案馆), a dependency injection (inversion of control) container for PHP4 (页面存档备份,存于互联网档案馆)
- PyContainer (页面存档备份,存于互联网档案馆), a dependency injection (inversion of control) container for Python (页面存档备份,存于互联网档案馆)
- Qt Ioc Container (页面存档备份,存于互联网档案馆), a dependency injection (inversion of control) container for C++ (页面存档备份,存于互联网档案馆)
- Introducing Castle, explains the problems that Inversion of control containers try to solve (using Castle Project)
- PocoCapsule (页面存档备份,存于互联网档案馆) An open source IoC and DSM framework for C++
- Domain Specific Modeling (DSM) in IoC frameworks (页面存档备份,存于互联网档案馆)