在MVC中,模型的作用是什么,它与SwingWorker有什么关系?

4

我读了很多关于Java、Swing、MVC和SwingWorker的内容,但是我对MVC中Model的作用完全感到困惑。

我正在构建一个应用程序,其中包含两个按钮:

  1. 选择文件
  2. 读取文件

还有一个用于记录日志的文本框。

我目前正在做的事情:

  1. 视图包含小部件但不包含逻辑
  2. 按钮的actionPerformed()方法调用控制器上的一个方法
  3. 控制器将获取所需数据(包括显示OptionPane.showOpenDialog())以获取文件
  4. 文件引用存储在模型中。
  5. 模型通过PropertyChangeSupport、观察者模式通知视图新文件的情况。
  6. 视图启用“读取文件”按钮

我的第一个问题:我应该在模型中存储状态吗?也就是说,与操作序列相关的信息:必须先选择文件,然后才能读取文件。那么我的模型将变成一个状态机。

我的第二个问题:让控制器显示OptionPane是否正确?

然后就开始有趣了。用户点击“读取文件”按钮。我做的事情与“选择文件”按钮大致相同。视图调用控制器,但是控制器使用SwingWorker读取文件,因为这不应该在EDT上完成。SwingWorker通过对视图的引用(SwingWorker.process()方法)发布中间日志消息,并将其添加到文本框中。控制器侦听来自SwingWorker的“状态”属性更改。当“状态”为“完成”时,控制器调用“get()”函数。如果一切正常,则结果设置在模型中。如果不行,则处理异常。

我的第三个问题,也是最重要的问题:难道不应该由模型来读取文件吗?MVC的整个重点是关注点分离,具有所有好处(可测试性等)。如果我想要一个新的视图(例如CLI),那么我的模型现在只是一个数据模型。它对如何读取文件毫无头绪!线程问题怎么办?

希望你能给我一些好的建议。互联网上有大量关于SwingWorker、MVC等的示例。但我的问题不在于如何针对它们进行编码,而在于如何进行设计。

1个回答

7

我认为你的想法基本正确。以下是对你的问题逐一答复:

1. 在 Model 中存储状态是否可行? 是的,你可以并且应该在 Model 中存储状态——Model 包含了状态和改变该状态的行为。

2. 让 Controller 显示一个选项卡是否正确? 是的——应用程序的设计(逻辑流程)决定了文件来自哪里。Model 并不关心如何获取要读取的文件名,它只关心获取文件名。流程属于 Controller 的领域。

3. Model 不应该执行文件读取吗? 同样是的,文件读取是 Model 的一部分。尽管 Controller 在调用 Swing Worker,但是 Swing Worker 在概念上是 Model 的一部分,至少是由 Swing Worker 执行的主要逻辑。理想情况下,加载文件的所有逻辑都应该存在于 Model 类中。然后 Controller 可以使用 Swing Worker 调用这些逻辑。Controller 决定文件加载应该在后台线程中进行,并指示 Model 从后台加载文件。Controller 的 Swing Worker 从 Model 接收加载进度事件,并通过调用 publish() 处理这些事件,然后通过 process() 更新 UI。

原则上,你应该能够将整个应用程序重写成一个控制台应用程序,而无需改变 Model。当然,视图会发生变化,但这是因为它现在必须使用标准输出而不是 Swing 来呈现 Model。最大的变化发生在 Controller 中——应用程序流程将不同(文件选择来自程序参数),Controller 不再监听按钮单击以指导流程,而是具有固定流程或通过标准输入与用户交互。控制器中的线程模型也不同——不需要担心 EDT,因此也不需要 Swing Worker。

因此,Model 负责状态和状态更改,View 负责呈现状态,而 Controller 则负责其他所有事情,特别是将 Model 连接到 View。


我看过的关于MVC和Swing最简洁的帖子之一 - 谢谢! - Hovercraft Full Of Eels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接