4

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

我正在构建一个有两个按钮的应用程序:

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

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

我目前在做什么:

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

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

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

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

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

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

4

1 回答 1

7

我认为你已经走上正轨了。一一回答您的问题:

1.我应该将状态存储在模型中吗? 是的,您可以并且应该在模型中存储状态——模型是改变该状态的状态和行为。

2.我让Controller显示OptionPane是否正确? 是的 - 应用程序设计(逻辑流程)决定文件来自哪里 - 模型当然不关心要读取的文件名是如何获得的,只是它得到一个文件名。flow 是控制器的域。

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

原则上,您应该能够将整个应用程序重写为控制台应用程序,而无需更改模型。自然,视图会发生变化,但这是因为它现在必须使用标准输出而不是 Swing 来呈现模型。最大的变化发生在控制器中——应用程序流程会有所不同(文件选择来自程序参数),控制器不再监听按钮点击来引导流程,而是有一个固定的流程,或者通过标准输入与用户交互。并且控制器中的线程模型不同 - 无需担心 EDT,因此无需摆动工人。

所以你看,模型负责状态并更改该状态,视图负责呈现状态,控制器完成其他所有事情,特别是将模型连接到视图。

于 2011-04-07T21:35:27.693 回答