如何解释对5岁孩子的依赖注射?[关闭]


208

有什么好的方法解释依赖项注入

我在Google上找到了几本教程,但是都没有一个假定读者只是Java初学者。您将如何向新手解释?


72
听起来那个孩子过着艰难的生活……
ire_and_curses

24
从“从前……”开始
马丁

1
我们是在谈论Java初学者还是五岁的孩子?
德鲁

2
#依赖注入#不依赖于学习者的年龄,每个人都一样
Rakesh Juyal 09年

2
Rakesh:JavaOne 2009入门视频的前提是即使Java开发人员也只有13年,因为Java是“无处不在”和“轻松”的。
埃斯科(Esko)

Answers:


789

我给您五岁的孩子打依赖药。

当您自己将物品从冰箱中取出时,可能会引起问题。您可能会打开门,可能会得到妈妈或爸爸不想要的东西。您甚至可能在寻找我们什至没有或已经过期的东西。

您应该做的是陈述一个需求,“我需要在午餐时喝点东西”,然后我们将确保您坐下吃饭时能得到一些东西。


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;
    }
}

到目前为止一切都很好。

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

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

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

 Address someAddress = ....
 Employee oscar = new Employee( someAddress ); 

以这种方式工作变得成问题,尤其是 当您要执行单元测试时。

当你需要测试一个特定的对象,主要问题就来了,你需要创建其他对象的实例,并最有可能你需要再创建实例对象做到这一点。链条可能变得难以管理。

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

  public Employee(){
  }

使用no args构造函数。

然后,您可以根据需要设置地址:

 Address someAddress = ....
 Employee oscar = new Employee();
 oscar.setAddress( someAddress ); 

现在,如果您具有多个属性或对象难以创建,那么这可能会很麻烦。

但是,考虑一下,假设您添加了Department属性:

  class Employee {
      private Address address;
      private Department department;

  ....

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

什么是依赖注入是所有关于它来帮你,好了,“注入”在你的代码这些依赖关系。大多数框架允许您通过在外部文件中指定要注入的对象来执行此操作。

假设一个虚拟的依赖注入程序的属性文件:

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

  #production setup 
  employee.address = RealAddress.class
  employee.department = RealDepartment.class

您将定义为给定场景注入的内容。

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

因此,下次您需要测试Employee该类时,可以注入模拟AddressDepartments对象,而不必为所有测试编写所有的set / get。更好的是,您可以在生产代码中注入实物 AddressDepartment对象,并且仍然对代码在测试时的工作充满信心。

差不多了。

我仍然认为您所要求的解释不适合5岁儿童使用。

我希望您仍然觉得它有用。


3
或者:依赖项注入是指您有一些东西可以为您设置依赖项。这通常是一个框架。:)
OscarRyz

2
确实是一个非常聪明的人。
OscarRyz

24

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

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

顺便说一句:在使用flickr照片来说明概念的现代演示风格中,这可以用瘾君子用毒品自焚来说明。哦,等等,这是注入依赖...好吧,抱歉,恶作剧。


10

我不知道任何简化的教程,但是我可以给您提供将近25 250字以内的版本:

使用依赖注入时,对象不会根据已知的东西配置自己的组件,而是由更高级别的逻辑配置对象,然后调用没有内置预知的组件。这个想法是使对象更多地是一个组件,而不是一个应用程序,从而在更高级别上重新分配配置任务。这使得该对象在将来或以其他配置更可能有用。

最好进行测试,最好是修改应用程序。一个典型的实现将配置放入XML中,并使用框架来动态加载类。


7

当您获得新的任天堂时,您只需使用按钮和触摸屏即可玩游戏。

但是在任天堂工厂,他们需要知道如何组装在一起。

当工厂里的聪明人拿出Nintendo DS时,内部将有所不同,但是您仍然会知道如何使用它。


5
这听起来更像是对接口或多态性的描述,但我相信您对于5岁的孩子实际上是可以理解的。
Natix 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.