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

发布于 2024-07-30 09:56:12 字数 745 浏览 7 评论 0原文

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

此外,我听说 Google Wave(一个 GWT 应用程序)是使用模型-视图-呈现器模式编写的。 最近发布了示例 MVP 应用,但查看代码,它并没有看起来没那么直观。

如果您要构建新的 GWT 应用程序,您会使用哪种架构? 您的选择有哪些优点和缺点?

谢谢,

马特

I just started a new GWT project for a client and I'm interested in hearing people's experience with various GWT MVC architectures. On a recent project, I used both GXT MVC, as well as a custom messaging solution (based on Appcelerator's MQ). GXT MVC worked OK, but it seemed like overkill for GWT and was hard to make work with browser history. I've heard of PureMVC and GWTiger, but never used them. Our custom MQ solution worked pretty well, but made it difficult to test components with JUnit.

In addition, I've heard that Google Wave (a GWT application) is written using a Model-View-Presenter pattern. A sample MVP application was recently published, but looking at the code, it doesn't seem that intuitive.

If you were building a new GWT application, which architecture would you use? What are the pros and cons of your choice?

Thanks,

Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅暮の光 2024-08-06 09:56:12

值得注意的是,google终于写出了使用mvp架构进行设计的教程。 它澄清了上面列出的 google i/o 演讲中的许多内容。 看一下:https://developers.google.com/web-toolkit/articles /mvp-架构

It's worth noting that google has finally written out a tutorial for designing using the mvp architecture. It clarifies a lot of the elements from the google i/o talk listed above. Take a looK: https://developers.google.com/web-toolkit/articles/mvp-architecture

夏雨凉 2024-08-06 09:56:12

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

在过去的几年里,我一直以一种非常被动的方式使用我自己的 MVP 实现,这种观点使自己受制于 Presenter 告诉他做的任何事情。

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

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

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

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

我的方法存在的问题:

  • 我当前的实现使得很难在不同屏幕的中央模型之间同步数据值。 假设您有一个显示一组类别的屏幕和另一个允许您添加/编辑这些项目的屏幕。 目前,跨屏幕边界传播这些更改事件非常困难,因为这些值被缓存在这些模型中,并且很难找到我们是否有些东西是脏的(在传统的 web1.0-html 中很容易) -dumb-terminal 是一种带有服务器端声明性缓存的场景)。
  • 视图的构造函数参数可以实现超级简单的测试,但是如果没有可靠的依赖注入框架,“onModuleLoad()”中将会有一些丑陋的工厂/设置代码。 当我开始这个的时候,我不知道 Google 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 优化。

I am glad this question has been asked, because GWT desperatley needs a rails-like way of structuring an application. A simple approach based on best practices that will work for 90 % of all use-cases and enables super easy testability.

In the past years I have been using my own implementation of MVP with a very passive view that enslaves itself to whatever the Presenter tells him to do.

My solution consisted of the following:

  • an interface per widget defining the methods to control the visual appearance
  • an implementing class that can be a Composite or use an external widget library
  • a central Presenter for a screen that hosts N views that are made up of M widgets
  • a central model per screen that holds the data associated with the current visual appearance
  • generic listener classes like "SourcesAddEvents[CustomerDTO]" (the editor does not like the real symbols for java generics here, so I used thoe brackets), because otherwise you will have lots of the same interfaces who just differ by the type

The Views get a reference to the presenter as their constructor parameter, so they can initialize their events with the presenter. The presenter will handles those events and notify other widgets/views and or call gwt-rpc that on success puts its result into the model. The model has a typical "Property[List[String]] names = ...." property change listener mechanism that is registered with the presenter so that the update of a model by an gwt-rpc request goes to all views/widgets that are interested.

With this appraoch I have gotten very easy testability with EasyMock for my AsynInterfaces. I also got the ability to easily exchange the implementation of a view/widget, because all I had to rewrite was the code that notified the presenter of some event - regardless of the underlying widget (Button, Links, etc).

Problems with my approach:

  • My current implementation makes it hard to synchronize data-values between the central models of different screens. Say you have a screen that displays a set of categories and another screen that lets you add/edit those items. Currently it is very hard to propagate those change events across the boundaries of the screens, because the values are cached in those models and it is hard to find our whether some things are dirty (would have been easy in a traditional web1.0-html-dumb-terminal kind of scenario with serverside declarative caching).
  • The constructor parameters of the views enable super-easy testing, but without a solid Dependency-Injection framework, one will have some UGLY factory/setup code inside "onModuleLoad()". At the time I started this, I was not aware of Google GIN, so when I refactor my app, I will use that to get rid of this boilerplate. An interesting example here is the "HigherLower" game inside the GIN-Trunk.
  • I did not get History right the first time, so it is hard to navigate from one part of my app to another. My approach is not aware of History, which is a serious downturn.

My Solutions to those problems:

  • Use GIN to remove the setup boilerplate that is hard to maintain
  • While moving from Gwt-Ext to GXT, use its MVC framework as an EventBus to attach/detach modular screens, to avoid the caching/synchronization issues
  • Think of some kind of "Place"-Abstraction like Ray Ryan described in his talk at I/O 09, which bridges the Event-Gap between GXT-MVC and GWTs-Hitory approach
  • Use MVP for widgets to isolate data access

Summary:

I dont think one can use a single "MVP" approach for an entire app. One definetly needs history for app-navigation, a eventbus like GXT-MVC to attach/detach screens, and MVP to enable easy testing of data access for widgets.

I therefore propose a layered approach that combines these three elements, since I believe that the "one-event-mvp-system"-solution wont work. Navigation/Screen-Attaching/Data-Access are three separate concerns and I will refactor my app (move to GXT) in the following months to utilize all three event-frameworks for each concerns separately (best tool for the job). All three elements need not be aware of each other. I do know that my solution only applies for GXT-projects.

When writing big GWT apps, I feel like I have to reinvent something like Spring-MVC on the client, which really sucks, because it takes a lot of time and brain-power to spit out something elegant as Spring MVC. GWT needs an app framework much more than those tiny little JS-optimizations that the compiler-guys work so hard on.

影子的影子 2024-08-06 09:56:12

以下是最近关于构建 GWT 应用程序的 Google IO 演示。

享受。

-J.P

Here is a recent Google IO presentation on architecting your GWT application.

Enjoy.

-JP

傲性难收 2024-08-06 09:56:12

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

If you're interested in using the MVP architecture, you might want to take a look at GWTP: http://code.google.com/p/gwt-platform/ . It's an open source MVP framework I'm working on, that supports many nice features of GWT, including code splitting and history management, with a simple annotation-based API. It is quite recent, but is already being used in a number of projects.

爱殇璃 2024-08-06 09:56:12

您应该查看 GWT Portlet。 我们在开发大型 HR 门户应用程序时开发了 GWT Portlet 框架,现在它是免费且开源的。 来自 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 Portlet 用 Ja​​va 代码实现,不包装任何外部 Javascript 库。 它不强加任何服务器端框架(例如 Spring 或 J2EE),但设计为与此类框架配合良好。

You should have a look at GWT Portlets. We developed the GWT Portlets Framework while working on a large HR Portal application and it is now free and open source. From the GWT Portlets website (hosted on Google code):

The programming model is somewhat similar to writing JSR168 portlets for a portal server (Liferay, JBoss Portal etc.). The "portal" is your application built using the GWT Portlets framework as a library. Application functionality is developed as loosely coupled Portlets each with an optional server side DataProvider.

Every Portlet knows how to externalize its state into a serializable PortletFactory subclass (momento / DTO / factory pattern) making important functionality possible:

  • CRUD operations are handled by a single GWT RPC for all Portlets
  • The layout of Portlets on a "page" can be represented as a tree of WidgetFactory's (an interface implemented by PortletFactory)
  • Trees of WidgetFactory's can be serialized and marshalled to/from XML on the server, to store GUI layouts (or "pages") in XML page files

Other important features of the framework are listed below:

  • Pages can be edited in the browser at runtime (by developers and/or users) using the framework layout editor
  • Portlets are positioned absolutely so can use scrolling regions
  • Portlets are configurable, indicate when they are busy loading for automatic "loading spinner" display and can be maximized
  • Themed widgets including a styled dialog box, a CSS styled button replacement, small toolbuttons and a HTML template driven menu

GWT Portlets is implemented in Java code and does not wrap any external Javascript libraries. It does not impose any server side framework (e.g. Spring or J2EE) but is designed to work well in conjunction with such frameworks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文