根据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不仅仅是对象或程序员与框架之间控制的反转。


当前回答

DIP vs DI vs IoC

[依赖倒置原则(DIP)]是SOLID[About]的一部分,它要求你使用抽象而不是实现

依赖注入(DI) -使用聚合而不是组合[关于]在这种情况下,外部对象负责内部的逻辑。哪一种方法使您拥有更动态和更可测试的方法

class A {
  B b

  //injecting B via constructor 
  init(b: B) {
     self.b = b
  }
}

控制反转(IoC)是一个非常高级的定义,它更多地是关于控制流的。最好的例子是控制反转(IoC)容器或框架。例如,GUI是一个框架,你没有一个控制,你能做的一切只是实现框架的接口,当一些动作发生在框架中时,它会被调用。这样,控制权就从应用程序转移到了正在使用的框架中

DIP +

class A {
  IB ib

  init(ib: IB) {
     self.ib = ib
  }
}

你也可以使用:

(工厂方法) (服务定位器) [ioc容器(框架)]

更复杂的例子

多层/模块结构中的依赖规则

伪代码:

interface InterfaceInputPort {
    func input()
}

interface InterfaceOutputPort {
    func output()
}

class A: InterfaceOutputPort {

    let inputPort = B(outputPort: self)

    func output() {
        print("output")
    }
}

class B: InterfaceInputPort {
    let outputPort: InterfaceOutputPort

    init(outputPort: InterfaceOutputPort) {
        self.outputPort = outputPort
    }

    func input() {
        print("input")
    }
}

其他回答

IoC概念最初出现在过程式编程时代。因此,从历史背景来看,IoC讨论了控制流所有权的倒置,即谁拥有以所需顺序调用函数的责任——无论是函数本身还是应该将其倒置到某个外部实体。

However once the OOP emerged, people began to talk about IoC in OOP context where applications are concerned with object creation and their relationships as well, apart from the control-flow. Such applications wanted to invert the ownership of object-creation (rather than control-flow) and required a container which is responsible for object creation, object life-cycle & injecting dependencies of the application objects thereby eliminating application objects from creating other concrete object.

从这个意义上讲,DI与IoC不同,因为它不是关于控制流的,但是它是一种Io*,即对象创建的所有权倒置。

我解释DI和IoC的方式有什么问题?

关于这个问题,我想说维基已经提供了详细易懂的解释。我引用这里最重要的。

国际奥委会的实施

在面向对象编程中,有几种基本的技术来实现 实现控制反转。这些都是: 使用依赖注入,用于 构造函数注入参数注入Setter注入 接口注入; 使用上下文化查找; 采用模板法设计模式; 使用策略设计模式

至于依赖注入

依赖注入是一种技术,一个对象(或静态的 方法)提供了另一个对象的依赖关系。依赖关系是 可以使用的对象(服务)。注入是传递 对使用它的依赖对象(客户端)的依赖。

我在Dzone.com上找到了最好的例子,这对理解IOC和DI之间的真正区别非常有帮助

“IoC就是让别人为你创建对象。”因此,与其在代码中写入“new”关键字(例如,MyCode c=new MyCode()),对象是由其他人创建的。这个“其他人”通常被称为IoC容器。这意味着我们将责任(控制)移交给容器以获得对象的实例,这称为控制反转。 意思是你不用new操作符来创建对象,而是让容器来为你做。

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

阅读全文IOC和全文DI

10c - DIP - DI

控制反转(IOC) 依赖倒置原理(DIP) 依赖注入(DI)

IOC:描述某些软件架构设计的一个方面的抽象原理,与过程式编程相比,系统的控制流是反向的。

2-DIP:是面向对象编程(Object - Oriented Programming, OOP)原理(SOLID中的D)。

3-DI:是一种实现控制反转的软件设计模式,允许程序设计遵循依赖反转原则。

IOC和DIP是两个不相交的集合,DIP是DI、服务定位器和其他一些模式的超集合

但是spring文档说它们是一样的。

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

在第一行“IoC也被称为依赖注入(DI)”。