控制反转与依赖注入

709
根据Martin Fowler撰写的论文,控制反转是一种程序控制流逆转的原则: 程序员不再控制程序的流程,而是由外部来源(框架、服务、其他组件)接管控制。就像我们把某物插入另一个物品中。他举了EJB 2.0的例子:

例如Session Bean接口定义了ejbRemove,ejbPassivate(存储到辅助存储器)和ejbActivate(从被动状态恢复),您无法控制何时调用这些方法,只能控制它们执行的操作。容器会调用我们,我们不会调用它。

这导致了框架和库之间的差异:

控制反转是使框架与库不同的关键部分。库本质上是一组函数,您可以调用这些函数,现在通常组织成类。每个调用都会执行一些工作,然后返回控制权给客户端。

我认为,DI是IOC的观点意味着对象的依赖性被倒置:它不再控制自己的依赖关系、生命周期等,而是由其他东西为您完成。但是,正如您告诉我的那样,手动进行DI并不一定是IOC。我们仍然可以进行DI而没有IOC。

然而,在这篇文章中(来自另一个面向C/C++的IOC框架pococapsule),它建议由于IOC和DI,IOC容器和DI框架比J2EE更加优越,因为J2EE将框架代码混合到组件中,因此不能使其成为纯旧的Java/C++对象(POJO/POCO)。

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

额外阅读以理解旧的基于组件的开发框架存在的问题,从而导致上述第二篇论文:控制反转的原因和内容(存档链接)

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


5
这里有一篇关于IoC vs DI(依赖注入)vs SL(服务定位器)的好文章:http://tinyurl.com/kk4be58 - 从URL中提取:IoC vs DI(依赖注入)?IoC是一个通用概念,其中流程控制从客户端代码反转到框架,“为客户端执行某些操作”。SL(服务定位器)和DI(依赖注入)是从IoC衍生出来的两种设计模式。 - Swab.Jat
顺便说一句,如果有人对依赖注入在咖啡店主题中如何有帮助感兴趣,我在这里写了一篇文章:digigene.com/design-patterns/dependency-injection-coffeeshop - Ali Nem
3
初学者可读的不错文章:https://asimplify.com/dependency-injection-inversion-control/该文章介绍了依赖注入和控制反转的概念,使用通俗易懂的语言解释了它们在软件开发中的作用和意义。阅读本文可以让初学者更好地理解这两个重要的概念,并为之后的学习打下基础。 - Khawaja Asim
依赖倒置:依赖于抽象而不是具体实现。控制反转:主程序与抽象之间的关系,以及主程序是系统的粘合剂。以下是一些讨论此问题的好文章:https://coderstower.com/2019/03/26/dependency-inversion-why-you-shouldnt-avoid-it/ https://coderstower.com/2019/04/02/main-and-abstraction-the-decoupled-peers/ https://coderstower.com/2019/04/09/inversion-of-control-putting-all-together/ - Daniel Andres Pelaez Lopez
1
阅读这篇深入的文章,它将澄清一切 https://martinfowler.com/articles/dipInTheWild.html#YouMeanDependencyInversionRight - Dusman
24个回答

0

我在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文章


0

1) DI是指子对象依赖于父对象。动词“依赖”很重要。 2) IOC是指子对象在平台下执行。平台可以是学校、大学、舞蹈班等。在任何平台提供者下,执行是一种具有不同含义的活动。

实际例子:

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

//ICO,DI,回溯10年,这是他们的方式:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

现在使用Spring 3、4或最新版本,代码如下:

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

总的来说,控制权从旧的耦合代码概念转变为像Spring这样的框架,使对象可用。就我所知,这就是IOC,而你知道的依赖注入是指我们使用构造函数或设置器将依赖对象注入到另一个对象中。注入基本上意味着将其作为参数传递。在Spring中,我们有基于XML和注释的配置,在其中定义bean对象并使用构造函数或设置器注入样式传递依赖对象。


0

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

控制反转的实现

在面向对象编程中,有几种基本技术可以实现控制反转。它们是:

  1. 使用服务定位器模式 使用依赖注入,例如 构造函数注入 参数注入 Setter注入 接口注入;
  2. 使用上下文查找;
  3. 使用模板方法设计模式;
  4. 使用策略设计模式

至于依赖注入

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接