2009-08-05 21 views
25

Acabo de comenzar un nuevo proyecto GWT para un cliente y estoy interesado en escuchar la experiencia de las personas con varias arquitecturas GWT MVC. En un proyecto reciente, utilicé ambos GXT MVC, así como una solución de mensajería personalizada (basada en Appcelerator's MQ). GXT MVC funcionaba bien, pero parecía exagerado para GWT y era difícil trabajar con el historial del navegador. He oído hablar de PureMVC y GWTiger, pero nunca los he usado. Nuestra solución MQ personalizada funcionó bastante bien, pero dificultó la prueba de componentes con JUnit.¿Cuál es su recomendación para diseñar aplicaciones GWT? ¿MVC, MVP o una solución de mensajería personalizada?

Además, he oído que Google Wave (una aplicación GWT) se escribe utilizando un patrón Model-View-Presenter. Se publicó recientemente una sample MVP application, pero mirando el código, no parece tan intuitivo.

Si estuviera construyendo una nueva aplicación GWT, ¿qué arquitectura usaría? ¿Cuáles son los pros y los contras de tu elección?

Gracias,

Matt

Respuesta

11

me alegro se ha hecho esta pregunta, porque GWT desperatley necesita una manera de estructurar una aplicación carriles-como. Un enfoque simple basado en las mejores prácticas que funcionará en el 90% de todos los casos de uso y permite una capacidad de prueba muy sencilla.

En los últimos años he estado usando mi propia implementación de MVP con una visión muy pasiva que se esclaviza a todo lo que el presentador le dice que haga.

Mi solución consistió en lo siguiente:

  • una interfaz por widget de la definición de los métodos para controlar la apariencia visual
  • una clase de implementación que puede ser un compuesto o utilizar una librería de widgets externa
  • una presentador central para una pantalla que aloja N vistas que están compuestas de M widgets
  • un modelo central por pantalla que contiene los datos asociados con la apariencia visual actual
  • clases de escucha genéricas como "SourcesAddEvents [CustomerDTO]" (al editor no le gustan los símbolos reales para los genéricos de Java aquí, así que usé los paréntesis), porque de lo contrario tendrá muchas interfaces iguales que simplemente difieren por el tipo

Las vistas obtienen una referencia del presentador como su parámetro de constructor, por lo que pueden inicializar sus eventos con el presentador. El presentador manejará esos eventos y notificará a otros widgets/vistas y/o llamará a gwt-rpc que, en caso de éxito, coloca su resultado en el modelo. El modelo tiene un mecanismo de detector de cambio de propiedad "Propiedad [Lista [Cadena]] nombres = ...." que está registrado con el presentador, de modo que la actualización de un modelo por una solicitud gwt-rpc va a todas las vistas/widgets que estan interesados.

Con este appraoch he conseguido una capacidad de prueba muy fácil con EasyMock para mis AsynInterfaces. También obtuve la capacidad de intercambiar fácilmente la implementación de una vista/widget, porque todo lo que tuve que reescribir fue el código que notificaba al presentador de algún evento, independientemente del widget subyacente (botón, enlaces, etc.).

problemas con mi enfoque:

  • Mi implementación actual hace que sea difícil para sincronizar datos entre los valores de los modelos centrales de diferentes pantallas. Supongamos que tiene una pantalla que muestra un conjunto de categorías y otra pantalla que le permite agregar/editar esos elementos. En la actualidad, es muy difícil propagar esos eventos de cambio a través de los límites de las pantallas, porque los valores están en caché en esos modelos y es difícil encontrar si algunas cosas están sucias (habría sido fácil en un web1.0-html tradicional). tipo de escenario de terminal de conmutación con almacenamiento en caché declarativo en el servidor).
  • Los parámetros de constructor de las vistas permiten realizar pruebas súper fáciles, pero sin un marco sólido de Dependencia-Inyección, uno tendrá un código de fábrica/configuración FEBRERO dentro de "onModuleLoad()". En el momento en que comencé esto, no estaba al tanto de Google GIN, así que cuando refactorice mi aplicación, la usaré para deshacerme de esta repetición. Un ejemplo interesante aquí es el juego "HigherLower" dentro del GIN-Trunk.
  • No obtuve historial correctamente la primera vez, por lo que es difícil navegar de una parte de la aplicación a otra. Mi enfoque no es consciente de la historia, que es una recesión grave.

mis soluciones a dichos problemas:

  • Uso GIN para eliminar el texto modelo de configuración que es difícil de mantener
  • Mientras se mueve desde GWT-Ext a GXT, utilice su marco MVC como EventBus a adjuntar/separar pantallas modulares, para evitar los problemas de almacenamiento en caché/sincronización
  • Piense en algún tipo de "lugar" -Abstracción como Ray Ryan describió en su charla en I/O 09, que une el Event-Gap entre GXT-MVC y Aproximación GWTs-Hitory
  • Uso MVP para los widgets para aislar el acceso a datos

Resumen:

No pienso que uno puede utilizar un solo enfoque de "MVP" para toda una aplicación. Uno definitivamente necesita historial para la navegación de aplicaciones, un bus de eventos como GXT-MVC para adjuntar/separar pantallas, y MVP para permitir pruebas fáciles de acceso a datos para widgets.

Por lo tanto, propongo un enfoque en capas que combine estos tres elementos, ya que creo que la solución "one-event-mvp-system" no funcionará. Navegación/Conexión de pantalla/Acceso a datos son tres preocupaciones diferentes y voy a refactorizar mi aplicación (pasar a GXT) en los próximos meses para utilizar los tres marcos de eventos para cada problema por separado (la mejor herramienta para el trabajo). Los tres elementos no necesitan estar conscientes el uno del otro. Sé que mi solución solo se aplica a los proyectos GXT.

Cuando escribo grandes aplicaciones GWT, siento que tengo que reinventar algo como Spring-MVC en el cliente, lo que realmente apesta, ya que toma mucho tiempo y capacidad cerebral escupir algo elegante como Spring MVC. GWT necesita un framework de aplicaciones mucho más que esas pequeñas y pequeñas optimizaciones JS en las que los compiladores trabajan tan duro.

+0

Pero esas pequeñas y pequeñas optimizaciones de JS son las que hacen que GWT sea tan rápido, y es una plataforma base para marcos más sofisticados que, si se hacen correctamente, podrían proporcionar todos los beneficios de la abstracción sin incurrir en el costo de muchas funciones profundas/despachos (GWT los optimizará/los alineará). – Chii

+0

Especialmente con Code-Splitting en 2.0, GWT es lo suficientemente rápido para el desarrollador de avería IMO. No me malinterpreten, no quiero descartar la importancia de esas optimizaciones. Pero los desarrolladores se enfrentan a problemas del mundo real y se beneficiarían mucho más de una forma convencional de hacer las cosas, un marco de aplicación, en este momento. – Sakuraba

+0

Sakuraba: estoy de acuerdo con usted en que GWT necesita algún tipo de mecanismo de convención sobre configuración para organizar el código. No me importa si se llama MVC o MVP, solo quiero algo simple y fácil de usar. He usado GXT MVC [1] y, en blanco, funciona, puede ser confuso de usar cuando implemente el historial. Para mí, la historia es uno de los aspectos más importantes de una aplicación de GWT y he descubierto que es más fácil implementarla antes que atornillarla después. Me estoy inclinando hacia MVP b/c Google lo recomienda (vea la respuesta de JP a continuación). [1] http://raibledesigns.com/rd/entry/gxt_s_mvc_framework –

7

Aquí hay una presentación reciente de Google IO en architecting your GWT application.

Disfrútalo.

-JP

+0

también de google io 2009: Voces que importan: GWT - Mejores prácticas de arquitectura: http://www.youtube.com/watch?v=Uwp3EVU5ePA –

1

Usted debe echar un vistazo a GWT Portlets.Desarrollamos el Marco de Portlets de GWT mientras trabajábamos en una gran aplicación de Portal de Recursos Humanos y ahora es de código abierto y gratuito. Desde el sitio web de GWT Portlets (alojado en el código de Google):

El modelo de programación es similar a escribir portlets JSR168 para un servidor de portal (Liferay, JBoss Portal, etc.). El "portal" es su aplicación creada utilizando el marco de portlets de GWT como una biblioteca. La funcionalidad de la aplicación se desarrolla como Portlets ligeramente acoplados, cada uno con un DataProvider opcional del lado del servidor.

Cada portlets sabe cómo exteriorizar su estado en una subclase PortletFactory serializable (Momento/DTO/patrón de fábrica) haciendo funcionalidad importante sea posible:

  • operaciones CRUD son manejados por un solo GWT RPC para todos los portlets
  • El diseño de los portlets en una "página" se puede representar como un árbol de WidgetFactory (una interfaz implementada por PortletFactory)
  • Los árboles de WidgetFactory se pueden serializar y organizar a/desde XML en el servidor para almacenar diseños de GUI (o "páginas") en los archivos de página XML

Otras características importantes del marco se enumeran a continuación:

  • páginas se pueden editar en el navegador en tiempo de ejecución (por los desarrolladores y/o usuarios) utilizando el editor de diseño de marco
  • portlets están posicionados absolutamente por lo que puede utilizar el desplazamiento regiones
  • portlets son configurables, indican cuando están ocupados de carga para la visualización automática "carga spinner" y pueden ser maximizados
  • widgets de temáticas que incluyen un cuadro de diálogo de estilo, una pocilga CSS Reemplazo del botón led, botones de herramientas pequeños y un menú impulsado por una plantilla HTML

GWT Portlets está implementado en código Java y no ajusta ninguna biblioteca Javascript externa. No impone ningún marco del lado del servidor (por ejemplo, Spring o J2EE), pero está diseñado para funcionar bien en conjunto con dichos marcos.

3

Si está interesado en utilizar la arquitectura MVP, es posible que desee echar un vistazo a GWTP: http://code.google.com/p/gwt-platform/. Es un marco de MVP de código abierto en el que estoy trabajando, que admite muchas características interesantes de GWT, incluida la división de código y la administración de historial, con una API basada en anotaciones simple. Es bastante reciente, pero ya se está utilizando en una serie de proyectos.

Cuestiones relacionadas