2013-03-03 113 views
0

以下代码有什么问题?IoC和依赖注入

public class DeDoper { 
    public boolean wackapediaOkToday() { 
     DnsResolver resolver = ResolverFactory.getInstance().makeResolver(); 
     return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9"); 
    } 
} 

为什么这个版本首选?

public class DeDoper { 
    @InjectService 
    private DnsResolver resolver; 

    public boolean wackapediaOkToday() { 
     return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9"); 
    } 
} 

我可以很容易模拟ResolverFactory.makeResolver(),这是与设置旋转变压器是最新的例子。

这是在this article从ProQuest.biz说:

此[首页]版本WackapediaOkToday是非常严格意义上“注入”了的DNSResolver(虽然这是无可否认不太像得到了一枪,更像是向服务员询问支票)。但它确实解决了测试问题,并解决了“乌龟一路下山”的问题。

链接到工厂 但是在这个[第一版本]方法中,我们实际上是“链接”到Factory类的。 (更糟糕的是,如果我们的工厂创建的对象轮流依赖,我们可能不得不在工厂中引入新的工厂)。我们还没有完全“颠倒”我们的控制,我们仍然从内部调用(控制)工厂我们的课程。

我们需要的是一种完全摆脱我们课程控制的方法,让他们告诉他们所得到的(他们的依赖)。

回答

2

比方说,你有一个可以有多个实现的服务,如“FileLocator”。它有一个FilesystemFileLocator,它将文件根目录的路径和S3FileLocator作为参数,S3FileLocator将S3凭证作为参数。前者将要求你编写一个服务定位器来确定你想要的版本,然后返回它。反过来,这些代码必须去获取你的数据,建立适当类型的文件定位器等。你正在做IOC容器应该为你做的事情。最重要的是,你已经注入了对特定创建方法的依赖。

在第二个版本中(通过注释或XML)定义了您想要的文件定位器类型。 IOC容器为你实例化和管理它。这是更少的代码,你必须维护。如果你想引入第三种类型的FileLocator,那么它的工作量也会减少。或者,也许你重构你的代码,所以文件定位器是单身人士,或者如果他们是单身人士,他们现在是工厂的新定位器,或者你想要池定位器实例。在所有这些情况下,如果您使用IOC容器,将会减少破损。