桌面应用程序中的MVC和Swing

7
在意识到自己完全忽略了MVC模式后,我尝试在一个带有Swing视图的应用程序中利用这个概念。现在我已经阅读了大部分关于MVC与Swing的文章,但仍感到有些困惑,因为对于我来说它太过复杂,我认为我需要一些基本的澄清,以免走错路。
我还想知道在真实项目中使用MVC模式的普遍程度。许多在线教程似乎将控制器省略并将其与模型混合,而我则被XSTL的业务逻辑功能所困惑。为什么要从JSP视图地址数据源?
除了这些想法,我的问题是:如果你有一个Swing组件,那么该组件中的事件监听器是否通过调用POJO控制器类中的(静态?)方法来更新组件状态,然后该控制器又从由POJO类层次结构和相关持久性组成的模型中获取适当的业务逻辑?

4
欢迎来到一只黄蜂巢。Swing将MVC范式混合,允许将“VC”虚拟化为单个组件。好与坏并不重要,事实就是如此。它所做的是试图将数据与视图分离开来。有些人认为应该将“控制”元素从视图中移出到自己的类中,但我个人认为这只会增加复杂度并引发更多问题 - 在我看来。一般来说,你的视图/控制器不应直接更改数据,这是模型的责任 - 在我看来。 - MadProgrammer
啊,谢谢。这让事情更清晰了一些。但是,你是否同意,如果GUI实现可能会改变(例如改为SWT),引入一个单独的控制器是有意义的?很遗憾我不能给你点赞--还没有足够的声望 :) - user1128272
只有当API/框架以类似的方式工作并具有某种类型的接口时,单独的控制器才有意义。话虽如此,如果您使用与模型编写方式相同的范例编写控制器(即从接口开始,转到抽象实现,然后允许多个具体实现),那么这是可行的。这需要考虑平衡,但由于我喜欢将所有内容抽象化,以便使用它的人不知道其实现,因此,我认为这是一个合理的想法。 - MadProgrammer
太棒了!对于主要GUI实现更改,我的初步结论是,研究事件监听器方法体(希望有良好的文档!)将提供几乎与将此功能移至单独控制器相同的价值,即使控制器可能会更轻便,因此更容易阅读。我认为您的评论节省了我很多时间!非常感谢您! - user1128272
谢谢你的建议,我会去做的! - user1128272
阅读这篇优秀的文章,作者使用MVC原则构建了一个真实的Swing GUI:http://java-articles.info/articles/?p=196 - Gilbert Le Blanc
2个回答

10

我做过很长时间的自由职业者,几乎90%的项目都涉及到Java Swing(桌面应用程序)。还有很多项目涉及从像Visual Fox Pro这样的语言迁移到Java,这非常痛苦,因为难点不在于思考已经完成的逻辑,而是将混乱的代码转化为符合良好实践和使用设计模式的漂亮代码,这就是为什么创建图表或脑海中的映射来分离代码的概念,遵循模型、视图、控制器的概念是个好主意。

正如之前提到的,MVC有助于拥有漂亮、可维护且易于阅读的代码,只要您遵循编程范例和良好实践即可。

视图:显然,与用户交互的部分(用户界面),在Swing中,您的窗口、框架、面板以及涉及应用程序所需的图形组件的所有代码。

控制器:涉及为应用程序建立的核心或业务逻辑,在这个“层”中,您应该包括功能和“我的应用程序将如何实现目标?”。

模型:与您管理的数据相关联,例如,表示您想要管理或维护的数据的实体和类。

应用MVC并不难,但是正如我之前提到的,有时从非MVC结构迁移代码到MVC结构的应用程序可能会很痛苦。使用MVC开始编码更容易一些。

我习惯使用maven并将我的应用程序分成小的“模块”,当然,您不需要maven,我只是在那个时候发现它很有用,但无论如何,您都可以通过将应用程序分成小项目来尝试练习或习惯MVC,例如:

Java Project 1:application-data-model(包含所有与数据管理相关的代码:实体、DTO、bean、dao)

Java Project 2:application-core-controller(包含所有业务逻辑和功能,如果要使您的代码在与视图交互时更加“透明”,则可以在这里使用Facade模式)

Java 项目 3:应用程序视图界面(包含所有的面板、框架和图形组件)。

按照这种方式工作有助于我(并迫使我)习惯将我的代码分开,并关注于对项目真正重要的部分。例如,如果我正在处理应用程序数据模型,我会专注于数据模型,而不是考虑业务逻辑或图形界面。

长话短说,也许有人能做得更好,但希望我能为你们提供帮助或至少给你们一些指引。

最好的问候。


谢谢!在我考虑接受这个答案之前,我需要一些时间来仔细思考一下。将业务逻辑放在控制器中似乎是合理的,但我的理解是这不是一个好主意,应该将其作为模型的一部分。 - user1128272
1
不用担心,我们在这里帮助你。你提到了一个很好的观点,我同意你的看法,即模型应该包含一些逻辑,但这些逻辑只应涉及数据访问和实体处理,如DAOS。在控制器中,您可以有其他流程,如薪资计算、责任委派。而且,正如你所写的那样,控制器将使用模型来管理或映射数据。您可以添加其他模式,如外观(如我所提到的),以将业务逻辑与视图分离得更清楚一些。 - Marcelo Tataje
1
@MarceloTataje:那么,当我将其与典型的Java Web应用程序进行比较时,Controller将映射到Service层,Model将映射到DAO层,而View将映射到Web层,对吗? 我之所以问这个问题是因为我将把我的Web应用项目转换为Java桌面应用程序。 - Shailesh Vaishampayan
1
@MarceloTataje:我可以使用Spring将我的控制器与模型和控制器与视图进行依赖注入,使用Hibernate进行数据持久化吗?只要我在Web应用程序中保持单个控制器(服务)和模型(DAO)的实例,这似乎很简单。此外,这些需要是无状态的,对吗? - Shailesh Vaishampayan
抱歉回复晚了,是的,你可以进行那种比较。在我看来,Spring 是我使用过的最好的框架之一。我真的很推荐,即使你不在 Web 环境中,将其转换为桌面应用程序,你也可以应用你在评论中提到的概念,Spring 将在简化许多迁移期间想要实现的功能方面做出良好的工作。一切取决于你,我的朋友,你可以使用标准组件实现功能,也可以从像 Spring 这样的框架中获得帮助,在这种情况下非常适合。 - Marcelo Tataje

3

首先,了解MVC的基本概念:

http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

接下来是在Swing应用程序中实现MVC的方法。不要将控制器功能与监听器功能混淆。

  1. UI控件和附加到它们上面的监听器应该在你的视图类中定义。
  2. 在任何事件发生时,当你需要调用业务逻辑时,需要调用控制器类。例如从数据库获取某些值。
  3. 控制器类应该与你的模型交互以获取数据并在必要时进行操作。
  4. 模型类应该处理数据。

使用MVC的想法是减少冗余代码并使代码更易管理。因此,如果你正在进行一些计算/操作,则可以将其移动到控制器中。控制器可以从需要相同内容的不同视图中调用。同样,多个控制器可以使用模型来获取数据。


我怀疑这就是所谓的厚控制器。我看到一些评论说控制器应该尽可能地薄,因此我认为所有可以在模型中处理的事情都应该在那里处理。也许我还处于困惑状态,但在接受/赞同您的答案之前,我会再多读一些资料。 - user1128272
那么你认为以下的思路是错误的吗?“我们很快发现,这种分割在实践中效果不佳,因为组件的视图和控制器部分需要紧密耦合(例如,编写一个不了解视图细节的通用控制器非常困难)。因此,我们将这两个实体合并成一个单独的UI(用户界面)对象,“(http://www.oracle.com/technetwork/java/architecture-142923.html) - user1128272
1
我同意实现纯MVC模型很难。这主要是因为它基于监听器模型工作。但我仍然相信,如果不是全部,很多代码可以移动到控制器中。简而言之,如果你喜欢MVC,你应该尽可能地遵守它 :-) - Juned Ahsan

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