gpt4 book ai didi

java - 我们可以将以下模式称为 DI 吗?

转载 作者:行者123 更新时间:2023-11-30 08:18:45 27 4
gpt4 key购买 nike

请原谅我的无知。我对 Java 很陌生。我研究过Spring DI。我们提供的任何基于 xml 或注释的配置都将用于以声明方式注入(inject)依赖项。但是,我认为我们不能动态更改依赖项。

因此,我创建了以下示例代码,它可以通过扩展类路径来提供依赖项(扩展类路径的代码未显示)。我们可以称之为 DI 吗?

标记界面

public interface IRule {

}

扩展 IRule 的接口(interface)

public interface IFooRule extends IRule {

public boolean validate(String json);

}

实现 IFooRule 的类

public class FooRuleImplemetor {

private FooRuleImplemetor implementor;

private FooRuleImplemetor() {
}

public boolean validateRule(String json) {
--Business Logic--
}

public static synchronized FooRuleImplemetor getInstance() {
if (implementor == null) {
implementor = new FooRuleImplemetor();
}
return implementor;
}
}

规则工厂。几乎任何 IS-A IRule 类的工厂类

public class RulesFactory {
public <T extends IRule> T getRuleImplementation(String clazz) {
try {
Class<?> ruleObject = Class.forName(clazz);
Method factoryMethod = ruleObject.getMethod("getInstance");
return (T) factoryMethod.invoke(null);
} catch (ClassNotFoundException e) {
logger.error("ClassNotFoundException", e);
} catch (IllegalAccessException e) {
logger.error("IllegalAccessException", e);
} catch (SecurityException e) {
logger.error("SecurityException", e);
} catch (NoSuchMethodException e) {
logger.error("NoSuchMethodException", e);
} catch (IllegalArgumentException e) {
logger.error("IllegalArgumentException", e);
} catch (InvocationTargetException e) {
logger.error("InvocationTargetException", e);
}
return null;
}
}

XML配置(仅部分)

<rule>
<action class="com.mycompany.FooRuleImplemetor">
<rule>

不属于类路径的xml将被动态读取。客户端将被移交 FooRuleImplemetor 的实例,如下所示(类从 xml 中读取)。

RulesFactory rulesFactory = new RulesFactory();
IFooRule fooRule = rulesFactory.getRuleImplementation(clazz);

这种模式叫什么名字?我们可以称之为依赖注入(inject)吗?

更新

我还想知道这种模式的潜在缺点(如果有的话)。是否有我可以使用的经过充分测试的替代模式?

最佳答案

你描述的更像是一个服务定位器,你用它来解决依赖关系。但依赖项本身并未注入(inject)——没有控制反转,您通过 rulesFactory.getRuleImplementation(clazz) 调用控制依赖项解析。

来自 Martin Fowler 的 Inversion of Control Containers and the Dependency Injection pattern (我建议您阅读):

The fundamental choice is between Service Locator and Dependency Injection. The first point is that both implementations provide the fundamental decoupling that's missing in the naive example - in both cases application code is independent of the concrete implementation of the service interface. The important difference between the two patterns is about how that implementation is provided to the application class. With service locator the application class asks for it explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control.

The disadvantages are arguable因为与大多数模式一样,它取决于您的要求。因此,我称它们为权衡取舍。

在这种情况下,它们是主要优势(解耦)的结果。在进行模块化设计时,请记住要最大限度地减少耦合,同时也要最大限度地提高内聚性。因此,请确保您没有创建粒度太细的模块。

列举一些权衡:

  • 它使您的代码不那么清晰。
  • 使维护更加困难。
  • 您丢失了一些编译时检查,这意味着潜在的运行时错误。

我的建议是,仅当您拥有具有多个实现的稳定接口(interface)时才使用它,或者至少您确定很快就会有另一个实现。只是不要去做,以防万一有一天您的界面可能会有另一种实现。如果这样做,您很可能会发现自己以牺牲编译时检查或 IDE 辅助之类的东西为代价进行了过度设计。

这是服务定位器和依赖注入(inject)模式的主要共同点。

关于java - 我们可以将以下模式称为 DI 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27254405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com