您对构建GWT应用程序的建议是什么? MVC,MVP或自定义消息传递解决方案?

时间:2009-08-05 16:38:33

标签: model-view-controller architecture gwt mvp puremvc

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

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

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

谢谢,

马特

5 个答案:

答案 0 :(得分:17)

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

答案 1 :(得分:11)

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

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

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

  • 每个窗口小部件的界面,用于定义控制视觉外观的方法
  • 可以是Composite或使用外部窗口小部件库的实现类
  • 一个屏幕的中央Presenter,用于承载由M个小部件组成的N个视图
  • 每个屏幕的中央模型,用于保存与当前视觉外观相关的数据
  • 泛型侦听器类,如“SourcesAddEvents [CustomerDTO]”(编辑器不喜欢这里的java泛型的真实符号,所以我使用了thoe括号),因为否则你会有很多相同的接口只是因类型不同而不同

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

有了这个appraoch,我已经通过EasyMock为我的AsynInterfaces提供了非常简单的可测试性。我还能够轻松地交换视图/小部件的实现,因为我必须重写的是通知演示者某些事件的代码 - 无论底层小部件(按钮,链接等)。

我的方法存在问题:

  • 我当前的实现使得很难在不同屏幕的中央模型之间同步数据值。假设您有一个显示一组类别的屏幕和另一个允许您添加/编辑这些项目的屏幕。目前很难在屏幕边界传播这些变化事件,因为这些值缓存在这些模型中,很难找到我们是否有些东西是脏的(在传统的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方法之间的事件差距连接起来
  • 使用MVP获取小部件以隔离数据访问

要点:

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

因此,我提出了一种结合这三个要素的分层方法,因为我认为“一事件 - mvp系统”解决方案不会起作用。导航/屏幕附加/数据访问是三个独立的问题,我将在接下来的几个月内重构我的应用程序(转移到GXT),分别为每个问题使用所有三个事件框架(工作的最佳工具)。所有这三个要素都不需要彼此了解。我知道我的解决方案仅适用于GXT项目。

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

答案 2 :(得分:7)

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

享受。

-jP

答案 3 :(得分:3)

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

答案 4 :(得分:1)

你应该看看GWT Portlets。我们在开发大型HR Portal应用程序时开发了GWT Portlets框架,现在它是免费的开源软件。来自GWT Portlets网站(托管在Google代码上):

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

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

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

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

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

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