假设我们有两个 EJB ServiceA
和 ServiceB
。 ServiceA
提供了 ServiceB
中所需的公共(public)方法。同时,ServiceB
存在于 ServiceA
中。
这种循环依赖有什么问题吗?
@Stateless
public class ServiceA implements IServiceA {
@EJB(mappedName = IServiceB.JNDI_NAME_LOCAL)
private IServiceB serviceB;
// ...
public void foo() {
// ...
}
}
@Stateless
public class ServiceB implements IServiceB {
@EJB(mappedName = IServiceA.JNDI_NAME_LOCAL)
private IServiceA serviceA;
// ...
private void bar() {
serviceA.foo();
}
}
我一直试图避免这样的架构,但一位同事最近引入了这种相互使用。我觉得在一个服务中使用一个服务是错误的,而该服务本身使用第一个服务,而第一个服务又使用第二个服务......你明白了。从技术上讲,这显然是可行的,但我对此并不完全满意,而是宁愿为 foo()
方法引入一个 ServiceC
。
所以我想知道:
这种循环依赖可以吗?
如果没有,是否存在不这样做的技术原因?
如果技术上可行,那么在设计方面是否有任何反对意见?
最佳答案
你的问题超出了EJB的范围,它是关于类之间的耦合。
Is it okay to have this circular dependency?
不可以,因为为了防止可维护性成本上升,如果不需要,两个类之间应该避免强耦合。
这里存在强耦合,因为 A 知道 B,B 也知道 A。
If not, are there technical reasons for not doing this?
对于某些 DI 容器,循环依赖的解决可能会很复杂,但实际上最严重的问题并不在这里。
通过双向依赖(A 看到 B,B 看到 A),无论我更改 A 或 B:方法(返回类型和参数)类层次结构等,另一个类都可能受到影响。
例如,在您的代码中,B 使用 A 的 foo()
方法。
假设 A 使用 B 的 bar()
方法。
如果我通过添加新参数来更改 A 的 foo()
方法,A 和 B 都会被修改,如果我更改 B 的 bar()
方法通过添加新参数,A 和 B 都再次被修改。
这清楚地表明了类之间的责任定义问题。它鼓励在未来的更改中混合职责,降低代码的可读性和设计的一致性,因此当修改这些类中的任何一个时,它都会产生副作用和回归。
虽然具有单向依赖关系(A 看到 B 但 B 看不到 A),如果我更改 A , B 不会受到影响,因为 B 不知道 A。
因此支持单向依赖。
Technically, this obviously works, but I'm not entirely happy with it and would rather introduce a ServiceC for the foo() method.
我们没有太多关于执行逻辑的细节,但您引入中间类以避免双向依赖的想法似乎相当不错,因为它可以防止强耦合
处理该问题的另一种方法是,如果通过移动 ServiceB 类中的 foo() 方法来更改类的职责是有意义的。这样,如果 serviceB 仅用于调用 foo() 方法,则 serviceB 就不再需要依赖于 serviceA。
关于java - 循环 EJB 依赖项的缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42389921/