注:本回答仅代表我个人观点。我仍然需要找到有关“最佳/最推荐”方式的不错的文献来编写 Swing UI 并将其与业务逻辑联系起来。但在我找到这一点之前,我会运用常识和个人经验。
我想说这两者都不是实现这一点的正确方法。在 MVC 中,视图只是向用户提供视觉信息的部分。然而,在ActionListener
当您按下按钮时,代码属于控制器,因为它很可能是业务逻辑(这是我根据您的代码片段做出的假设。如果您的按钮仅执行 UI 操作(例如启用另一个组件),则操作侦听器应完全包含在视图中).
所以我会在控制器中公开这些方法,例如如果您目前有ActionListener
like
public void actionPerformed( ActionEvent e ){
doSomeStuff( UI info, event info );
}
where UI info
是从视图中获取的信息并且event info
从事件中获取的信息,我将在控制器上引入公共方法
public void doSomeStuff( UI info, event info )
并从视图中调用该方法。这有两个主要好处:
- 仅存在从视图到控制器的依赖关系,而不是从控制器到视图的依赖关系。如果控制器包含业务逻辑,那么您很可能希望在 SwingUI 之外重用该代码。这里不需要依赖 Swing 类。一个例子是单元测试。如果您的控制器不依赖于 UI,您可以轻松测试应用程序的控制器模型部分,并使用 API 遵循与通过 UI 调用这些调用时相同的代码路径。
- 您可以完全调整您的 UI,并决定用另一个您无法附加的组件来替换该按钮
ActionListener
无需重写您的控制器和视图。
Edit
虽然我认为我的帖子的上述部分仍然有效,但我必须承认,在阅读完维基百科 MVC 页面 http://en.wikipedia.org/wiki/Model-view-controller在trashgod 的回答中提到(他在其中一条评论中提到过),上面只是对MVC 模式以及如何在Swing 应用程序中实现它的一种解释。
查看该 Wiki 页面,它将 MVC 中的三个组件定义为(总结):
-
Model:管理应用程序域的行为和数据
-
View:将模型渲染成适合交互的形式,通常是用户界面元素
-
控制器:接收用户输入并通过调用模型对象来发起响应
我的解释/意见/首选方式是拥有一个模型和一个控制器,如果需要多个视图(或者例如在测试零视图时)。控制器不直接接收用户输入(这相当于让它在视图上注册侦听器),但提供 API 挂钩来将用户输入传递到其中。这提供了一种可以处理用户输入的“抽象控制器”,但视图仍然需要将真实的用户输入事件转换为控制器可以理解的事件/信息。因此,这意味着我可以轻松创建 MVC 的测试“视图”端以及真正的“视图”端,而无需更改控制器或模型中的任何内容。
另一种解释是控制器和视图之间有更紧密的耦合(它们真正相互依赖)。这也意味着,如果您决定从 Swing UI 视图切换到命令行视图,您可能还必须更改控制器。这是更好还是更差......我认为这是个人品味的问题。
我原来的答案中唯一不太好的地方是我将业务逻辑定位在控制器部分,而 Wiki 页面明确指出它位于模型中。我可能对一些简单的 Ruby on Rails 实验感到困惑,其中模型只不过是一个数据访问层。我的错 ...