0

我是新手,我想了解什么时候在 Java 中使用 DI 是合适的。假设我需要使用不同的 ping 参数 ping 不同的网络:

PingParams 类:

public class PingParams {
int timeout;
int retries;
}

PingResult 类:

public class PingResult {
int ttl;
boolean available;
}

PingService 类:

public class PingService {

private PingParams pingParams;

@Inject
public PingService(PingParams pingParams) {
    this.pingParams = pingParams;
}

public PingResult ping(String ip) {
    // ping using timeout and retries from pingParams
    return new PingResult();
}
}

客户端:

public class Client {

@Inject
PingService pingService;

private List<PingResult> doPing() {
    List<PingResult> ret = new ArrayList<>();
    String[] ips = new String[] {"127.0.0.1","127.0.0.2"};
    for (String ip : ips) {
        PingResult pr = pingService.ping(ip);
        ret.add(pr);
    }
    return ret;
}

public static void main(String[] args) {
    List<PingResult> prs = new Client().doPing();
    System.out.println(prs);
}
}

我有 2 个注入点:

  1. 我在 PingService 的构造函数中注入 PingParams。

这个对吗?我的意思是,除非您创建一些“Produces”注释方法,否则 DI 容器无法知道超时并重试注入 PingParams,即使在这种情况下,它也需要大量工作来创建对象!但是当然你需要为每个网络创建几个,你如何使用 DI 来做到这一点?

  1. 我在客户端注入 PingService。

看起来是合法的,但 PingService 依赖于 PingParams,它将我们带到第 1 号注入点。

在我看来,使用 DI 的唯一合适方法是使用没有依赖项(因此无用)的类,或者使用非常简单的服务类,您可以将所有依赖项作为参数传递给服务方法。例如,在 ping 方法中接受 ip 和 PingParams 的 PingService,同样,此类将没有依赖关系......

我错过了什么吗?您如何将 DI 与这些“数据”类一起使用,这些类仅包含用于保存数据的字段 (PingParams)?在这些情况下是否应该避免 DI?谢谢

4

2 回答 2

2

一般来说,您应该只对非数据类使用依赖注入。如果您的类同时包含数据和非数据协作者,则可以使用辅助注入

您所说的 ping 参数确实应该在您的应用程序启动时绑定到一个实例,并在必要时注入。对于您的示例,这确实是很多代码,但从长远来看,它可以在更大的项目中保持良好和干净。

总结一下:在应用程序启动时绑定 PingParam(例如作为 Singleton),将其注入 PingService,并在没有 DI 的情况下创建 PingResult(如您所做的那样)。

对于依赖注入最佳实践,我推荐阅读Prasanna 的依赖注入

于 2013-12-29T15:40:55.300 回答
0

假设我们谈论的是 CDI/Weld。假设您的PingParams类存储在数据库中,作为从某个表加载的配置。将其抽象出来会很有意义,只需为PingParams从数据库读取数据并返回此数据元素的类提供一个生产者方法。为此配置使用数据对象并为其提供生产者并不是一个坏主意。

于 2013-12-30T02:27:14.907 回答