根据Martin Fowler所写的论文,控制反转是程序控制流反转的原理:由外部源(框架、服务、其他组件)控制程序流,而不是由程序员控制程序流。就像我们把一个东西插入另一个东西。他提到了一个关于EJB 2.0的例子:

例如,会话Bean接口 定义ejbRemove, ejbPassivate (存储到二级存储),以及 ejbActivate(从被动恢复 状态)。你不能控制时间 这些方法被调用,只是什么 他们做的事。集装箱召唤我们,我们 别这么说。

这就导致了framework和library的区别:

控制反转是一个关键的部分 框架与框架的区别是什么 图书馆。图书馆本质上是一个 一组你可以调用的函数, 这些日子通常组织成 类。每次调用都要做一些工作 将控制权返回给客户端。

我认为,DI是IOC的观点,意味着对象的依赖关系是倒置的:而不是它控制自己的依赖关系、生命周期……其他东西可以帮你。但是,正如你告诉我的DI by hands, DI不一定是IOC。我们仍然可以有DI,没有IOC。

然而,在本文中(来自pococapsule, C/ c++的另一个IOC框架),它指出,由于IOC和DI, IOC容器和DI框架要比J2EE优越得多,因为J2EE将框架代码混合到组件中,因此它不是普通的旧Java/ c++对象(POJO/POCO)。

依赖注入模式以外的控制反转容器(存档链接)

附加阅读,了解旧的基于组件的开发框架的问题,这导致了上面的第二篇论文:为什么和什么反转控制(档案链接)

我的问题:IOC和DI到底是什么?我很困惑。基于pococapsule, IOC不仅仅是对象或程序员与框架之间控制的反转。


当前回答

我认为这个想法可以清楚地展示,而不需要进入面向对象的杂草,这似乎混淆了这个想法。

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

如果您倾斜头部并眯起眼睛,就会发现DI是IoC的一种特殊实现,具有特定的关注点。您不是将模型和行为注入到应用程序框架或更高阶操作中,而是将变量注入到函数或对象中。

其他回答

DI和IOC是两种主要侧重于提供组件之间的松耦合的设计模式,或者简单地说,这是一种解耦对象之间传统依赖关系的方法,这样对象之间就不会紧密相连。

通过下面的例子,我试图解释这两个概念。

以前我们是这样写代码的

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

使用Dependency注入,依赖注入器将负责对象的实例化

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

上述将控件交给其他容器(例如容器)进行实例化和注入的过程可以称为控制反转,IOC容器为我们注入依赖项的过程可以称为依赖项注入。

IOC是程序控制流颠倒过来的原则:不是由程序员控制程序的流,而是由程序通过减少程序员的开销来控制流程。程序用来注入依赖的过程称为DI

这两个概念一起工作为我们提供了一种编写更加灵活、可重用和封装的代码的方法,这使得它们在设计面向对象的解决方案时成为重要的概念。

也推荐阅读。

什么是依赖注入?

你也可以在这里查看我的一个类似的答案

控制反转和依赖注入的区别

控制反转(IoC)模式是关于提供任何类型的回调,它“实现”和/或控制反应,而不是我们自己直接操作(换句话说,反转和/或重定向控制到外部处理程序/控制器)。

例如,不是让应用程序调用库(也称为工具包)提供的实现,而是库和/或框架调用应用程序提供的实现。

依赖注入(DI)模式是IoC模式的一个更具体的版本,其中实现通过构造函数/设置器/服务查找传递到对象中,对象将“依赖”这些以正确地行为。

每个DI实现都可以被认为是IoC,但不应该称之为IoC,因为实现依赖注入比实现回调更难(不要使用通用术语“IoC”来降低产品的价值)。

例如,不使用DI的IoC将是Template模式,因为实现只能通过子类化来更改。

依赖注入框架被设计为使用依赖注入,并且可以定义接口(或Java中的注释)以方便在实现中传递。

IoC容器是可以在编程语言之外工作的依赖注入框架。在某些情况下,您可以在元数据文件(例如XML)中配置要使用的实现,这是侵入性较小的。有一些可以做IoC,这通常是不可能的,比如在切入点注入实现。

参见Martin Fowler的文章。

IOC表示外部类管理应用程序的类,而外部类表示容器管理应用程序类之间的依赖关系。 IOC的基本概念是程序员不需要创建对象,而是描述如何创建对象。

IoC容器执行的主要任务是: 实例化应用程序类。配置对象。组装对象之间的依赖关系。

DI是通过使用setter注入或构造函数注入在运行时提供对象依赖关系的过程。

简而言之,IoC是一个更广泛的术语,包括但不限于DI

术语控制反转(IoC)最初指的是任何一种编程风格 框架或运行时控制程序流

在DI有名字之前,人们开始把管理依赖的框架称为反转 很快,IoC的含义逐渐转向了特定的含义:对依赖项的控制反转。

控制反转(IoC)意味着对象不创建它们所依赖的其他对象来完成工作。相反,他们从外部来源(例如,xml配置文件)获取所需的对象。

依赖注入(DI)意味着这是在没有对象干预的情况下完成的,通常由传递构造函数参数和设置属性的框架组件完成。

我认为这个想法可以清楚地展示,而不需要进入面向对象的杂草,这似乎混淆了这个想法。

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

如果您倾斜头部并眯起眼睛,就会发现DI是IoC的一种特殊实现,具有特定的关注点。您不是将模型和行为注入到应用程序框架或更高阶操作中,而是将变量注入到函数或对象中。