2009-08-05 56 views
25

我刚刚为客户启动了一个新的GWT项目,并且我很有兴趣听到人们使用各种GWT MVC体系结构的经验。在最近的一个项目中,我使用了GXT MVC以及一个自定义消息解决方案(基于Appcelerator's MQ)。 GXT MVC工作正常,但对于GWT来说似乎有点矫枉过正,并且很难与浏览器历史记录一起工作。我听说过PureMVCGWTiger,但从未使用过它们。我们的自定义MQ解决方案工作得很好,但很难用JUnit测试组件。您对构建GWT应用程序有什么建议? MVC,MVP还是自定义消息解决方案?

另外,我听说Google Wave(一个GWT应用程序)是使用Model-View-Presenter模式编写的。最近发布了一个sample MVP application,但看着代码,它看起来并不那么直观。

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

感谢,

马特

回答

11

我很高兴这个问题已经被问,因为GWT desperatley需要构建的应用程序的轨道状的方式。一种基于最佳实践的简单方法,适用于所有使用案例的90%,并且具有超易测试性。

在过去的几年里,我一直在使用自己的MVP实现方式,他的观点非常消极,无论主持人告诉他做什么。

我的解决方案包括以下部分:

  • 每插件限定所述的方法来控制视觉外观
  • 实现类,可以是一个复合或使用外部部件库的接口
  • 一个中央主持人用于承载由M个部件组成的N个视图的屏幕
  • 每个屏幕的中央模型,其保存与当前视觉外观关联的数据
  • 类似于“SourcesAddEvents [CustomerDTO]”的编辑器(编辑器不喜欢这里的java泛型的真实符号,所以我使用了thoe括号),因为否则的话,您将拥有许多相同的接口,这些接口只是类型不同

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

有了这个Appraoch,我已经用EasyMock为我的AsynInterfaces获得了非常简单的可测试性。我还可以轻松地交换视图/小部件的实现,因为我必须重写的是通知某个事件的发布者的代码 - 无论底层部件(按钮,链接等)如何。

问题,我的方法:

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

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

  • 使用GIN删除设置样板,是很难维持
  • 虽然从GWT-Ext的移动GXT,使用它的MVC框架作为EventBus到连接/分离模块化屏幕,以避免缓存/同步问题考虑某种类型的“放置” - 像Ray Ryan在I/O 09的演讲中描述的那样,它在GXT-MVC和GWTs-Hitory方法
  • 使用MVP的小工具隔离数据访问

摘要:

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

因此,我提出了一个分层的方法,结合了这三个要素,因为我相信“one-event-mvp-system”-solution不会起作用。导航/屏幕附加/数据访问是三个独立的问题,我将在接下来的几个月里重构我的应用程序(转移到GXT),以分别利用所有三个事件框架(最佳工具)。所有这三个元素都不需要意识到对方。我知道我的解决方案只适用于GXT项目。在编写大型GWT应用程序时,我觉得我不得不在客户端重新创建类似Spring-MVC的东西,这真的很糟糕,因为花费大量时间和大脑力量去吐出像Spring MVC这样优雅的东西。 GWT需要一个应用程序框架,远远超过编译器人员如此努力工作的微小JS优化。

+0

但这些小小的JS-优化是什么使GWT如此之快 - 这是更复杂的框架基础平台,如果正常进行,可以提供抽象的所有优点,而不会产生很多深功能承滴盘的成本/发送(GWT将优化/内联它们)。 – Chii 2009-08-06 10:54:02

+0

特别是在2.0中的代码分割时,GWT对于平均开发人员IMO来说足够快。不要误会我的意思,我不想忽视这些优化的重要性。但是开发人员面临现实世界的问题,并且会从传统的做事方式 - 应用程序框架 - 中获益更多。 – Sakuraba 2009-08-06 14:33:09

+0

Sakuraba - 我同意你的看法,GWT需要某种约定优先配置机制来组织代码。我不在乎它是否被称为MVC或MVP,我只是想要一些简单易用的东西。 我已经使用了GXT MVC [1],它的工作原理是白色,当你实现历史记录时,它可能会令人困惑。对我而言,历史是GWT应用程序最重要的方面之一,我发现它很容易早期实现,而不是事后实施。 我倾向于MVP b/c谷歌推荐它(见JP的回答如下)。 [1] http://raibledesigns.com/rd/entry/gxt_s_mvc_framework – 2009-08-07 13:03:01

7

以下是architecting your GWT application上最近的一次Google IO演示文稿。

享受。

-jP

+0

同样来自google io 2009:重要声音:GWT - 架构最佳实践:http://www.youtube.com/watch?v = Uwp3EVU5ePA – 2009-08-07 20:49:24

1

你应该看看GWT Portlets。我们在开发大型HR门户应用程序时开发了GWT Portlets框架,现在它已成为免费且开源的。从GWT的Portlet网站(托管在谷歌代码):

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

每个portlet知道如何外部化的状态转变为可序列化PortletFactory子(时代报/ DTO /工厂模式),使得重要的功能可能:

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

其它重要特征列出如下:

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

GWT Portlets在Java代码中实现,并且不包装任何外部Javascript库。它没有强加任何服务器端框架(例如Spring或J2EE),而是设计成与这样的框架结合使用。

3

如果你有兴趣使用MVP架构,你可能想看看GWTP:http://code.google.com/p/gwt-platform/。这是一个我正在开发的开源MVP框架,它支持GWT的许多优秀功能,包括代码拆分和历史管理,以及基于注释的简单API。这是相当新的,但已经在一些项目中使用。

相关问题