如何解释5岁的依赖注射?

use*_*313 208 design-patterns dependency-injection inversion-of-control

什么是解释依赖注入的好方法?

我在Google上找到了几个教程,但没有一个能让读者认为只是Java初学者的教程.你会如何向新手解释这个?

Joh*_*sch 789

我给你五岁儿童的依赖注射.

当你自己从冰箱里取出东西时,你可能会引发问题.你可能会把门打开,你可能得到妈咪或爸爸不希望你拥有的东西.您甚至可能正在寻找我们甚至没有或已经过期的东西.

你应该做的是说明需要,"我需要在午餐时喝点东西",然后当你坐下来吃饭时我们会确保你有东西.


Osc*_*Ryz 93

那这个呢?

如果您有一个类Employee且该员工有一个类,Address 您可以Employee按如下方式定义类:

class Employee {
    private Address address;

    // constructor 
    public Employee( Address newAddress ) {
        this.address = newAddress;
    }

    public Address getAddress() {
    return this.address;
    }
    public void setAddress( Address newAddress ) {
        this.address = newAddress;
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切看起来都很好

此代码显示员工与其地址之间的HAS-A关系,这很好.

现在,这种HAS-A关系在它们之间创建了依赖关系.问题出在构造函数中.

每次要创建Employee实例时,都需要一个Address实例:

 Address someAddress = ....
 Employee oscar = new Employee( someAddress ); 
Run Code Online (Sandbox Code Playgroud)

以这种方式工作会成为问题,尤其是 当您想要执行单元测试时.

主要问题是当你需要测试一个特定对象时,你需要创建一个其他对象的实例,并且很可能你需要创建一个其他对象的实例来做到这一点.链条可能变得无法管理.

为避免这种情况,您可以像这样更改构造函数:

  public Employee(){
  }
Run Code Online (Sandbox Code Playgroud)

使用no args构造函数.

然后您可以随时设置地址:

 Address someAddress = ....
 Employee oscar = new Employee();
 oscar.setAddress( someAddress ); 
Run Code Online (Sandbox Code Playgroud)

现在,如果您有多个属性或者难以创建对象,这可能会拖累.

然而,考虑一下,比方说,你添加Department属性:

  class Employee {
      private Address address;
      private Department department;

  ....
Run Code Online (Sandbox Code Playgroud)

如果您有300名员工,并且所有员工都需要拥有相同的部门,并且必须在其他一些对象(例如公司的部门列表或每个部门拥有的角色等)之间共享相同的部门,那么您将会很难看到Department对象的可见性,并通过所有对象网络共享它.

什么是依赖注入,它可以帮助您在代码中"注入"这些依赖项.大多数框架允许您通过在外部文件中指定要注入的对象来执行此操作.

假设虚构依赖注入器的属性文件:

  #mock employee
  employee.address = MockAddress.class
  employee.department = MockDepartment.class

  #production setup 
  employee.address = RealAddress.class
  employee.department = RealDepartment.class
Run Code Online (Sandbox Code Playgroud)

您将定义为给定方案注入的内容.

Dependency Injector框架将为您设置正确的对象,因此您不必编写代码setAddresssetDepartment.这可以通过反射或通过代码生成或其他技术来完成.

因此,下次您需要测试Employee该类时,您可以注入模拟AddressDepartments对象,而无需为所有测试编写所有set/get代码.更好的是,您可以在生产代码中注入实际 AddressDepartment对象,并且仍然可以确保您的代码在测试时运行.

这几乎就是它.

我仍然不认为这个解释适合你要求的5岁.

我希望你仍然觉得它很有用.

  • 或者:依赖注入是指你有*为你设置依赖项的东西.这个东西通常是一个框架.:) (3认同)
  • 确实非常聪明. (2认同)

Ned*_*der 24

在编写类时,使用其他对象是很自然的.例如,您可能拥有数据库连接,或者您使用的某些其他服务.这些其他对象(或服务)是依赖项.编写代码的最简单方法就是创建和使用其他对象.但这意味着您的对象与这些依赖关系之间存在不灵活的关系:无论您为何调用对象,它都使用相同的依赖关系.

更强大的技术是能够创建对象并为其提供依赖性.因此,您可以创建要使用的数据库连接,然后将其交给您的对象.这样,您可以在不同时间创建具有不同依赖关系的对象,从而使您的对象更加灵活.这是依赖注入,您可以将依赖项"注入"对象.

顺便说一句:在使用flickr照片来说明概念的现代演示风格中,这可以通过吸毒者用药物射击自己来说明.哦,等等,这是注射依赖...好吧,对不起,糟糕的笑话.


Dig*_*oss 10

我不知道任何简化的教程,但我可以给你一个近25个 250字或更少的版本:

通过依赖注入,对象不会基于它已经知道的事物来配置它自己的组件,而是由更高级别的逻辑配置对象,然后它调用它没有内置预知的组件.我们的想法是使对象更多地成为组件而不是应用程序,从而将配置任务重新定位到更高级别.这使得该对象在将来或使用不同的配置时更有可能有用.

它更适合测试,在修改应用程序时更好.典型的实现将配置放在XML中,并使用框架动态加载类.


WW.*_*WW. 7

当你获得一个新的任天堂,你可以使用按钮和触摸屏来玩游戏.

但在任天堂工厂,他们需要知道如何将它们组合在一起.

当工厂的聪明人带出任天堂DS时,内部会有所不同,但你仍然会知道如何使用它.

  • 这听起来更像是对接口或多态的描述,但我认为*实际上*对于一个5岁的孩子来说是可理解的. (5认同)