【发布时间】:2013-01-18 20:39:08
【问题描述】:
我正在开发一个包含多个子系统的 java swing 应用程序。出于所有意图和目的,假设我正在制作一个带有随机附加功能的互联网聊天程序。该功能将是...一个调度程序,您可以在其中设置时间并在该时间收到提醒,并通知您朋友列表中的每个人您收到提醒。
将此功能组织成三个类是有意义的:GUI、ChatManager 和 Scheduler。这些类将执行以下操作:
GUI - 定义所有挥杆组件和事件
ChatManager - 创建聊天连接、发送和接收消息、管理好友列表
调度程序 - 监控系统时间、发送通知、存储文件以记住会话之间的事件
要使程序正常工作,这些类中的每一个都必须能够与其他两个类进行通信。 GUI 需要告诉 ChatManager 何时发送消息并告诉 Scheduler 何时开始监控。 ChatManager 需要在收到消息时在 GUI 上显示消息,最后,Scheduler 需要在完成时通知 GUI,并向 ChatManager 发送状态更新或其他任何内容。
当然,这里描述的类都非常简单,让它们直接相互通信可能不是一个坏主意。但是,为了这个问题,我们假设交互要复杂得多。
例如,假设我们可以向调度程序注册特定事件而不是特定时间。发送消息时,我将消息发送给用户,将其存储在日志文件中,创建事件对象并将其传递给调度程序,并处理沿途可能引发的任何异常。
当通信变得如此复杂时,如果与这些类的通信可能发生在许多不同的地方,那么维护您的代码就会变得很困难。例如,如果我要重构 ChatManager,我可能还需要对 GUI 和调度程序(以及其他任何东西,如果我引入新的东西)进行重大更改。这使得代码难以维护,也让我们睡眠不足的程序员在进行更改时更容易引入错误。
最初似乎最有意义的解决方案是使用调解器设计模式。这个想法是这三个主要类都没有直接相互感知,相反,每个类都感知到一个中介类。反过来,中介类定义了处理三个类之间通信的方法。因此,例如,GUI 将调用中介类中的 sendMessage() 方法,中介将处理需要发生的所有事情。最终,这将三个主要类解耦,对其中一个类的任何更改都可能只会导致对中介者的更改。
但是,这带来了两个主要问题,最终导致我来到这里寻求反馈。它们如下:
问题
许多任务需要更新 GUI,但中介者不知道组件。 - 假设用户启动程序并输入他们的用户名/密码并单击登录到登录聊天服务器。登录时,您希望通过在登录屏幕上显示文本来报告登录过程,例如“正在连接...”、“正在登录...”或“错误”。如果您在 Mediator 类中定义登录方法,那么显示这些通知的唯一方法是在 GUI 类中创建一个公共方法来更新正确的 JLabel。最终,GUI 类将需要大量方法来更新其组件,例如显示来自特定用户的消息、在用户登录/注销时更新您的朋友列表等。此外,您必须预料到这些 GUI 更新可能随时随机发生。可以吗?
Swing 事件调度线程。您将主要从在 EDT 上执行的组件 ActionListener 调用中介方法。但是,您不想在 EDT 上发送消息或读/写文件,否则您的 GUI 将变得无响应。因此,在中介对象中提供一个 SingleThreadExecutor 是否是个好主意,中介对象中的每个方法都定义一个可以提交给执行线程的新可运行对象?此外,更新 GUI 组件必须在 EDT 上进行,但该 Executor 线程将调用方法来更新 GUI 组件。因此,GUI 类中的每个公共方法都必须将自身提交给 EDT 以执行。那有必要吗?
对我来说,在 GUI 类中有一个方法来更新每个以某种方式与外部通信的组件似乎需要做很多工作,其中每个方法都有额外的无意中检查它是否在 EDT 上,并且否则将自己添加到 EDT。此外,Mediator 类中的每个公共方法都必须执行类似的操作,将 Runnable 代码添加到 Mediator 线程或启动工作线程。
总的来说,使用 Mediator 模式维护应用程序的工作量似乎几乎与没有它的应用程序一样多。那么,在这个例子中,如果有什么不同的话,你会做些什么呢?
【问题讨论】: