【问题标题】:Removing circular dependencies in asynchronous java application?删除异步 Java 应用程序中的循环依赖项?
【发布时间】:2018-09-15 14:51:35
【问题描述】:

我已经阅读了依赖注入和接口,但我仍然对在我的情况下解耦包的最佳方法感到困惑。假设我在 UIPackage 中有一个 UIClass:

package UIPackage;

import NetworkPackage.NetworkClass

class UIClass() {
    public static void displayMessage(String message) {
        // show the message on screen
    }

    private static void messageEntered(String message) {
        NetworkClass.sendMessage(message);
    }
}

和 NetworkPackage 中的 NetworkClass:

package NetworkPackage;

import UIPackage.UIClass;

class NetworkClass() {
    public static void sendMessage(String message) {
        // send the message to the network
    }

    private static void messageReceived(String message) {
        UIClass.displayMessage(message)
    }
}

这些包相互依赖,但我想让网络包独立于 UI 包工作以消除依赖循环。到目前为止,我发现这样做的唯一方法是为 UIClass 创建一个接口来实现(UIInterface),然后将 UIInterface 的一个实例传递给构造函数中的 NetworkController 或其他东西。这似乎只是让事情变得更加复杂,因为该接口需要在它自己的包中,然后包含在两个原始包中。

我应该为这种类型的接口创建第三个包吗?我应该离开循环依赖而不担心它吗?

说明 1 这不是我实际使用的代码,我只是这样命名包,以便示例更清晰。该应用程序使用多个线程,这就是为什么NetworkClass 需要对UIClass 的引用,因为它一直在等待新消息,而 UI 可能在不同的线程上做其他事情。当收到消息时,它需要能够更新 UI 并显示消息。这些包有许多其他类做其他事情,但为了举例,这些类都是公开的。

【问题讨论】:

  • 您不能离开循环依赖,因为您将无法构建您的代码。看起来你需要重新设计你的架构。如果A依赖B,B依赖A。应该有一个模块C,A和B都依赖。因此,从 A 中取出 B 所依赖的部分和 B 中 A 所依赖的部分,然后将它们放入 C 中。希望有所帮助
  • 另外,包名应该小写:)
  • 理想的答案是肯定的,你应该创建一个接口来消除循环依赖。您认为它很复杂,但实际上并不复杂,它为您提供了可扩展性。

标签: java dependencies package decoupling coupling


【解决方案1】:

循环依赖通常意味着两个组件/事物之间的强耦合。
有问题吗? 它经常发生,但并非总是如此。

3 个可能导致问题的示例:

1) 如果依赖项尝试通过将另一个作为参数传递来创建自己。这显然是不可能的。使用在实例构造后设置一个或两个依赖项的方法是解决它的一种方法。

2) 如果依赖项的代码更改足够频繁,因为对一个类的更改可能会产生副作用或破坏另一个类的代码。
就像这些类是一个类,而事实并非如此。

3) 如果您想在其他上下文或应用程序中单独重用其中一个依赖项。
你不能,因为没有另一个就不能生活。
所以它可以打败减少或防止依赖重用性。

【讨论】:

    【解决方案2】:

    当然你应该关心,就像你应该注意 Java 编码约定一样。

    我认为在包名中嵌入“包”和在类名中嵌入“类”是脑死的。匈牙利符号在几十年前就失宠了。把它们拿出来。

    这是一个糟糕的设计。

    我不知道您的 Network 课程是干什么用的。我认为Network 没有理由知道或关心调用它的Client。如果Client 引用了注入到其构造函数中的Network,它应该能够使用它来发送调用、获取响应并显示它。没有充分的理由给Client 引用Network

    不再有循环依赖。

    我希望它更像是四层架构:

    客户端 -> 控制器 -> 服务 -> 持久性

    这是一种典型的 Web 应用程序的请求/响应安排。 UI 向控制器/侦听器发送请求,控制器/侦听器协调服务和持久性以实现用例并将响应发送回 UI。

    如果您采用基于事件的异步架构,情况就会发生变化。

    【讨论】:

    • 请看我上面的说明。
    猜你喜欢
    • 2011-04-29
    • 2022-08-18
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    相关资源
    最近更新 更多