【问题标题】:Write own dependency injection编写自己的依赖注入
【发布时间】:2013-12-03 14:43:52
【问题描述】:

我们正在开发一个应用程序。该应用程序将部署在专有的事件处理引擎中。我们不应该对 DI 使用任何 api,例如 spring core。目前还没有专有的 DI 框架。所以想法是写一个和一个简单的。

谁能提供一些意见。

我的想法是编写一个包含静态方法的工厂类。静态方法将返回我们想要的类的实例。现在我们只需要一个实例。我假设以下类型的代码

public final class MyFactory {

    private static ClassA classA = new ClassA();
    private static ClassB classB = new ClassB();

    private MyFactory() {
        throw new CustomException("Cannot create instance");
    }

    public static ClassA getClassAInstance() {
        return classA;
    }

    public static ClassB getClassBInstance() {
        return classB;
    }
}

以后我会这样用

public class SomeRandomClass {

    private ClassA classA = MyFactory.getClassAInstance();
}

我看到的另一件事是我不需要测试 ClassA 和 ClassB。测试 SomeRandomClass 将涵盖 ClassA 和 ClassB。因为静态内容总是首先加载。因此,在测试 SomeRandomClass 时,我总是有 ClassA 实例。因此,在 SomeRandomClass 中的某个方法上编写 junit 将调用 ClassA 中的方法。这样好吗?

我的做法是否正确?我还能改进它吗?

【问题讨论】:

  • 为什么你应该重新发明一个非常复杂的轮子,而不是使用工作、测试和理解的框架?
  • Guice 并不复杂,你可以试试。
  • 尝试查看 Guice 背后的代码 - 是的,它很复杂。但它的用法很简单,就像 CDI/Weld 一样。这就是为什么最好使用已经存在的东西。问题是,到目前为止,在这个线程中呈现的内容中,我认为还没有真正的理由实际应用依赖注入。依赖注入不是对象实例化的直接替代品。
  • “简单”DI 就像在某处的字符串值上执行 forName 一样简单。您真正有哪些具体要求?
  • 您对MyFactory 所做的操作称为服务定位器模式;它被认为是anti-pattern。您应该改用构造函数注入。

标签: java spring dependency-injection


【解决方案1】:

首先,工厂 API 不应该像那样直接引用具体的类实现。这有点违背了目的。您将无法在不重新编译的情况下更改具体类,并且您将无法执行诸如为测试和开发截取接口之类的事情。

然后,假设您想要单例(这不是您的示例的编写方式),您需要确保您的工厂方法在生成单例时是线程安全的。

您至少应该让您的工厂返回真正的单例接口实例。然后,您可以实现某种配置系统并使用 Java 反射 API 来确定应该在运行时创建哪些具体类。这也将使您能够执行诸如存根用于测试或开发的接口之类的事情。

这不是真正的 DI。它还有很多东西,它在可读性/可写性/可配置性/可维护性方面的好处远远超出了工厂所能提供的。我不确定为什么在专有软件中使用 Spring 会成为问题。 AFAIK Spring 的许可证并不强制代码开源或免费......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多