代码之家  ›  专栏  ›  技术社区  ›  Matt Raible

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

  •  25
  • Matt Raible  · 技术社区  · 15 年前

    我刚为一个客户启动了一个新的GWT项目,我很想听听人们对各种GWTMVC架构的体验。在最近的一个项目中,我同时使用了 GXT MVC 以及自定义消息传递解决方案(基于 Appcelerator's MQ )Gxt MVC工作正常,但对于GWT来说,这似乎是杀伤力过大,很难在浏览器历史中发挥作用。我听说过 PureMVC GWTiger 但从未使用过。我们的定制MQ解决方案工作得很好,但是很难用JUnit测试组件。

    此外,我听说GoogleWave(一个GWT应用程序)是使用模型视图演示者模式编写的。A sample MVP application 是最近出版的,但看看代码,它似乎不那么直观。

    如果您正在构建一个新的GWT应用程序,您将使用哪个体系结构?你选择的利弊是什么?

    谢谢,

    马特

    5 回复  |  直到 12 年前
        1
  •  17
  •   David    12 年前

    值得注意的是,Google最终编写了一个使用MVP架构进行设计的教程。它澄清了上面列出的谷歌I/O对话中的许多元素。看一看: https://developers.google.com/web-toolkit/articles/mvp-architecture

        2
  •  11
  •   Sakuraba    15 年前

    我很高兴有人问这个问题,因为GWT绝望地需要一种类似Rails的方法来构造应用程序。一种基于最佳实践的简单方法,适用于90%的所有用例,并且实现了超简单的可测试性。

    在过去的几年里,我一直在使用我自己的MVP实现,用一种非常被动的观点,将自己奴役于演讲者告诉他的任何事情。

    我的解决方案包括:

    • 每个小部件的一个接口,定义控制视觉外观的方法
    • 一个实现类,它可以是复合的,也可以使用外部小部件库。
    • 一个屏幕的中央演示者,它承载由m小部件组成的n个视图。
    • 每个屏幕的中心模型,用于保存与当前视觉外观关联的数据
    • 泛型侦听器类,比如“SuxSerdDaveNoS[Cuffer-Dto]”(编辑器不喜欢这里的Java泛型的实际符号,所以我使用了THORE括号),因为否则,将有很多相同类型的接口,它们只是类型不同而已。

    视图将引用演示者作为其构造函数参数,因此可以使用演示者初始化事件。演示者将处理这些事件,并通知其他小部件/视图,或者调用GWT RPC,成功后将其结果放入模型中。该模型有一个典型的“属性[列表[字符串]]名称=…”属性更改侦听器机制,该机制在演示者中注册,以便GWT RPC请求对模型的更新转到所有感兴趣的视图/小部件。

    有了这个应用程序,我可以很容易地用easymock对我的非对称接口进行测试。我还能够轻松地交换视图/小部件的实现,因为我需要重写的只是通知演示者某些事件的代码——不管底层小部件(按钮、链接等)是什么。

    我的方法有问题:

    • 我当前的实现使得在不同屏幕的中心模型之间同步数据值变得困难。假设您有一个屏幕显示一组类别,另一个屏幕允许您添加/编辑这些项目。目前,很难将这些更改事件传播到屏幕边界,因为这些值缓存在这些模型中,很难找到某些内容是否脏(在传统的Web1.0-html-dumb-terminal场景中,服务器端声明性缓存很容易实现)。
    • 视图的构造器参数支持超简单的测试,但是没有一个可靠的依赖注入框架,在“onmoduleLoad()”中会有一些丑陋的工厂/设置代码。在我开始这个的时候,我不知道google gin,所以当我重构我的应用程序时,我将使用它来去掉这个样板文件。一个有趣的例子是杜松子酒后备箱里的“higherlower”游戏。
    • 我第一次没有正确地了解历史,所以很难从我的应用程序的一个部分导航到另一个部分。我的方法不了解历史,这是一个严重的衰退。

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

    • 使用GIN移除难以维护的设置样板
    • 当从GWText迁移到Gxt时,使用其MVC框架作为事件总线来连接/分离模块化屏幕,以避免缓存/同步问题。
    • 想想类似RayRyan在I/O09上的演讲中所描述的某种“场所”抽象,它弥合了Gxt-MVC和GWTS Hitory方法之间的事件鸿沟。
    • 对小部件使用MVP来隔离数据访问

    总结:

    我认为一个人不能对整个应用程序使用单一的“MVP”方法。一个明确需要应用程序导航的历史记录,一个像gxt-mvc这样的事件总线来连接/分离屏幕,以及MVP来实现对小部件数据访问的简单测试。

    因此,我提出了一种将这三个元素结合在一起的分层方法,因为我相信“单事件MVP系统”——解决方案是行不通的。导航/屏幕附加/数据访问是三个独立的问题,我将在接下来的几个月内重构我的应用程序(转到Gxt),以便分别为每个问题使用所有三个事件框架(工作的最佳工具)。这三个要素不需要相互了解。我知道我的解决方案只适用于Gxt项目。

    在编写大型GWT应用程序时,我觉得我必须在客户端上重新设计一些像SpringMVC这样的东西,这真的很糟糕,因为要将一些优雅的东西吐出SpringMVC需要很多时间和脑力。GWT需要一个应用程序框架,而不仅仅是那些小的JS优化,而编译器们正在努力工作。

        3
  •  7
  •   JP Richardson    15 年前

    这是最近的谷歌IO演示 architecting your GWT application .

    享受。

    JP

        4
  •  3
  •   Philippe Beaudoin    14 年前

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

        5
  •  1
  •   David Tinker    15 年前

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

    编程模型与为门户服务器(Liferay、JBoss Portal等)编写JSR168 portlet有些相似。“门户”是使用GWTPortlets框架作为库构建的应用程序。应用程序功能是作为松散耦合的portlet开发的,每个portlet都有一个可选的服务器端数据提供程序。

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

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

    框架的其他重要特征如下:

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

    GWT Portlet是用Java代码实现的,不封装任何外部JavaScript库。它不强制使用任何服务器端框架(如Spring或J2EE),但设计用于与此类框架结合使用。