8

我正在寻找一篇文章或教程,该文章或教程提供了一个示例,说明最新的 MVC 模式(2.0?)在 Swing 框架中应该是什么样的。

此外,由于更习惯于分层架构,我想知道域对象或 POJO 是如何融入图片的。我是否正确假设它们是分开的并由模型调用?至于模式本身,在将类分组到包方面是否有广泛使用的约定?

TIA,

詹姆斯·P。

4

1 回答 1

26

这是个大问题。我将与您分享我对这个主题的一些想法,看看会产生什么结果。

Swing 比 Model->View->Controller 更多的是 Model->View。Model->View 的问题在于,通常 Swing 应用程序子类化一个 View 对象,并且该对象成为该视图的 View 和 Controller 合并为一个。在大型应用程序中加班会导致很多问题和意大利面条式代码。

几年来我一直在做的是创建一个单独的对象,称为控制器,它不扩展任何 UI 类。在这方面,它是一个普通的旧对象。这个控制器将负责实例化视图的顶级组件,将监听器连接到视图以响应用户,并转身调用模型来完成工作。

View 将继承 Swing。View 负责响应鼠标事件、键盘事件等。任何类型的 Swing 特定事件都在 View 中处理。它还将提供用于更新控制器将用于回调以更新 UI 的视图的高级方法。经典摇摆模型也是视图的一部分,因为您选择的组件与您将使用的模型非常相关。View 还负责向 Controller 发送高级事件,而 Controller 负责响应这些高级事件。这些事件可能是 UserEvent.ADD、UserEvent.EDIT、AuthenticationEvent.LOG_IN、AuthenticationEvent.LOG_OUT 等。这些事件是应用程序事件,读起来更像是产品经理可能识别的。控制器不响应 Mouse、ChangListener 等。我' 我实际上为这些构建了我自己的 EventDispatch 和 Event 框架,因为 Swing 很难有效地扩展和使用。该视图的工作原理类似于:

public void mouseClicked( MouseEvent evt ) {
   User u = getUserAt( evt.getPoint() );
   dispatch( new UserEvent( UserEvent.EDIT, u ) );
}

在我的控制器中,我有连接到这些事件的简单方法。这里可能是一个例子:

@EventCallback( command = "exit" )
public void exit( AppEvent evt ) {
    onExit();
}

@EventCallback(command = "help.about")
public void showAbout(AppEvent evt ) {
    audioFinderFrame.showAboutDialog(engine.getLicenseInfo());
}

@EventCallback( command = MediaSourceEvent.START_REFRESH )
public void refreshStarted(final MediaSourceEvent event) {
   if( frame != null ) frame.refreshMediaSource( event.getSource(), true );
}

注释是我必须将事件侦听器方法快速添加到 EventDisptach 源的扩展。但是,关键是控制器上的每个方法都是使用高级事件从视图中调用的。这使得 Controller 在某种程度上与视图的显示方式隔离开来。Controller 的登录方法不必担心视图是由哪些组件构成的。他只是接收一个事件并执行工作。控制器负责应用程序的流程。

由于事件系统与 Swing 分离,我在模型层中重用它,因此模型可以将事件发送回控制器,控制器可以将这些更改传递给 UI。

模型和控制器是 POJO。他们了解事件,但仅此而已。该模型是应用程序的逻辑,包括 DAO 级别、可能执行后台作业的服务、与服务器对话的任何服务层以及大多数人可能会说是 DTO 的对象。我没有规定 DTO 应该只是简单的 getter/setter 结构。我确实允许其中一些逻辑,因为它们是在所有层之间浮动的一件事。因为每一层都可以访问它们,它们提供了一个很好的地方来集中每一层可以重用的逻辑。View、Controller 和 Model 可以访问这些方法,所以为什么不将它们放在在它们之间移动的对象中。

通常,此逻辑更接近于业务逻辑或模型维护逻辑。我很小心将更大的架构系统耦合到这些方法。这些方法不会与数据库对话,也不会调用服务器端方法,因此它们不会将引用带回更大的架构部分。它们具有 DTO 的所有优点:轻量级、易于构建、低依赖性,但仍保持面向对象设计的原则:封装、重用和信息隐藏。

我还开始使用 Spring 将模型的各个部分与它们的依赖关系和控制器对模型的依赖关系连接起来。我发现这个模型效果很好,而且比不使用它更令人愉快。如果我正在使用这些技术,那么访问 Spring JDBC 模板和 JMS 模板等技术也很不错。但是,它是可选的。

我从不重用控制器。控制器是系统中最具体的东西,通用性只会使它们更难维护。通用性确实属于视图和模型,因为它使开发更容易。所以设计模式倾向于发现自己在这些方面,但很少在控制器中。控制器是简单的方法来回调用。

我发现这样做使构建 Swing UI 变得更加容易,也更加直接。我不太可能通过同时收听和操作两个控件进入无限事件循环。我还发现测试和拆分系统更容易,因为我的大部分逻辑都存在于 Swing 掌握之外。这使得功能测试成为可能,而无需尝试模拟鼠标点击等的巨大工具包。

这里没有很多代码来说明抱歉,但希望这会有所帮助。

于 2010-02-26T01:11:37.197 回答