25

我刚刚为一个客户启动了一个新的 GWT 项目,我很想听听人们对各种 GWT MVC 架构的体验。在最近的一个项目中,我使用了GXT MVC以及自定义消息传递解决方案(基于Appcelerator 的 MQ)。GXT MVC 工作正常,但对于 GWT 来说似乎有点过头了,而且很难处理浏览器历史记录。我听说过PureMVCGWTiger,但从未使用过它们。我们的自定义 MQ 解决方案运行良好,但很难使用 JUnit 测试组件。

此外,我听说 Google Wave(一个 GWT 应用程序)是使用 Model-View-Presenter 模式编写的。最近发布了一个示例 MVP 应用程序,但是查看代码,它似乎并不那么直观。

如果您正在构建一个新的 GWT 应用程序,您会使用哪种架构?你选择的优缺点是什么?

谢谢,

马特

4

5 回答 5

17

值得注意的是,google 终于写出了使用 mvp 架构进行设计的教程。它阐明了上面列出的 google i/o talk 中的许多元素。看看:https ://developers.google.com/web-toolkit/articles/mvp-architecture

于 2010-01-03T22:48:27.813 回答
11

我很高兴有人问了这个问题,因为 GWT desperatley 需要一种类似于 rails 的方式来构建应用程序。一种基于最佳实践的简单方法,适用于 90% 的所有用例,并实现超级容易的可测试性。

在过去的几年里,我一直在使用我自己的 MVP 实现,并以一种非常被动的观点来奴役 Presenter 告诉他做什么。

我的解决方案包括以下内容:

  • 每个小部件的接口定义控制视觉外观的方法
  • 一个实现类,可以是 Composite 或使用外部小部件库
  • 一个屏幕的中央演示者,它托管由 M 个小部件组成的 N 个视图
  • 每个屏幕的中心模型,保存与当前视觉外观相关的数据
  • 通用侦听器类,例如“SourcesAddEvents[CustomerDTO]”(编辑器不喜欢这里的 java 泛型的真实符号,所以我使用了方括号),否则您将拥有许多相同的接口,只是类型不同

视图获取对演示者的引用作为其构造函数参数,因此它们可以使用演示者初始化它们的事件。演示者将处理这些事件并通知其他小部件/视图,或者调用 gwt-rpc 成功将其结果放入模型中。该模型有一个典型的“Property[List[String]] names = ....”属性更改侦听器机制,该机制已向演示者注册,以便通过 gwt-rpc 请求更新模型到所有视图/小部件感兴趣。

通过这种方法,我的 AsynInterfaces 使用 EasyMock 获得了非常容易的可测试性。我还能够轻松地交换视图/小部件的实现,因为我所需要重写的只是通知演示者某些事件的代码 - 无论底层小部件(按钮、链接等)如何。

我的方法存在的问题:

  • 我当前的实现很难在不同屏幕的中心模型之间同步数据值。假设您有一个显示一组类别的屏幕和另一个允许您添加/编辑这些项目的屏幕。目前很难将这些更改事件传播到屏幕的边界,因为这些值被缓存在这些模型中,并且很难找到我们是否有些东西是脏的(在传统的 web1.0-html 中很容易-dumb-terminal 一种带有服务器端声明式缓存的场景)。
  • 视图的构造函数参数可以实现超级简单的测试,但是如果没有可靠的依赖注入框架,“onModuleLoad()”中就会有一些 UGLY 工厂/设置代码。在我开始这个的时候,我不知道谷歌 GIN,所以当我重构我的应用程序时,我会用它来摆脱这个样板。一个有趣的例子是 GIN-Trunk 中的“HigherLower”游戏。
  • 我第一次没有得到正确的历史记录,所以很难从我的应用程序的一个部分导航到另一个部分。我的方法没有意识到历史,这是一个严重的衰退。

我对这些问题的解决方案:

  • 使用 GIN 删除难以维护的设置样板
  • 从 Gwt-Ext 迁移到 GXT 时,使用其 MVC 框架作为 EventBus 来附加/分离模块化屏幕,以避免缓存/同步问题
  • 想一想 Ray Ryan 在 I/O 09 上的演讲中描述的某种“地点”-抽象,它弥合了 GXT-MVC 和 GWTs-Hitory 方法之间的 Event-Gap
  • 为小部件使用 MVP 来隔离数据访问

概括:

我不认为可以为整个应用程序使用单一的“MVP”方法。应用程序导航肯定需要历史记录,需要像 GXT-MVC 这样的事件总线来附加/分离屏幕,以及 MVP 来轻松测试小部件的数据访问。

因此,我提出了一种结合这三个元素的分层方法,因为我相信“one-event-mvp-system”解决方案不会起作用。导航/屏幕附加/数据访问是三个独立的关注点,我将在接下来的几个月中重构我的应用程序(迁移到 GXT),以分别针对每个关注点使用所有三个事件框架(该工作的最佳工具)。所有三个元素不需要相互了解。我知道我的解决方案只适用于 GXT 项目。

在编写大型 GWT 应用程序时,我觉得我必须在客户端重新发明类似 Spring-MVC 的东西,这真的很糟糕,因为要吐出像 Spring MVC 这样优雅的东西需要大量的时间和脑力。GWT 需要一个应用程序框架,而不是那些编译器人员努力工作的微小的 JS 优化。

于 2009-08-06T08:15:20.037 回答
7

这是最近关于构建 GWT 应用程序的 Google IO 演示文稿。

享受。

-J.P

于 2009-08-06T17:20:47.507 回答
3

如果您对使用 MVP 架构感兴趣,您可能想看看 GWTP:http ://code.google.com/p/gwt-platform/ 。这是我正在开发的一个开源 MVP 框架,它支持 GWT 的许多不错的特性,包括代码拆分和历史管理,以及一个简单的基于注释的 API。它是最近才出现的,但已经在许多项目中使用。

于 2010-04-13T19:14:50.217 回答
1

您应该看看GWT Portlets。我们在开发大型 HR 门户应用程序时开发了 GWT Portlets 框架,它现在是免费和开源的。从 GWT Portlets 网站(托管在 Google 代码上):

编程模型有点类似于为门户服务器(Liferay、JBoss Portal 等)编写 JSR168 portlet。“门户”是使用 GWT Portlets 框架作为库构建的应用程序。应用程序功能被开发为松散耦合的 Portlet,每个 Portlet 都带有一个可选的服务器端 DataProvider。

每个 Portlet 都知道如何将其状态外部化为可序列化的 PortletFactory 子类(momento / DTO / factory 模式),从而使重要功能成为可能:

  • CRUD 操作由所有 Portlet 的单个 GWT RPC 处理
  • Portlet 在“页面”上的布局可以表示为 WidgetFactory 的树(由 PortletFactory 实现的接口)
  • 可以在服务器上对 WidgetFactory 的树进行序列化和编组到 XML 或从 XML 编组,以将 GUI 布局(或“页面”)存储在 XML 页面文件中

该框架的其他重要功能如下所列:

  • 可以使用框架布局编辑器在运行时(由开发人员和/或用户)在浏览器中编辑页面
  • Portlet 是绝对定位的,因此可以使用滚动区域
  • Portlet 是可配置的,指示它们何时忙于加载以自动显示“加载微调器”,并且可以最大化
  • 主题小部件,包括样式对话框、CSS 样式按钮替换、小工具按钮和 HTML 模板驱动菜单

GWT Portlets 以 Java 代码实现,不包装任何外部 Javascript 库。它不强加任何服务器端框架(例如 Spring 或 J2EE),但旨在与此类框架一起很好地工作。

于 2009-08-19T20:01:51.173 回答