Section 11: J2EE Patterns
 

11.1 Given a scenario description with a list of issues, select a pattern that would solve the issues. The list of patterns you must know are: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, and Transfer Object.

11.2 Match design patterns with statements describing potential benefits that accrue from the use of the pattern, for any of the following patterns: Intercepting Filter, Model-View-Controller, Front Controller, Service Locator, Business Delegate, and Transfer Object.

Intercepting Filter

Este pattern esta relacionado con todas esas tareas que a veces tenemos que hacer que no estan relacionadas con la lógica de negocios de nuestra aplicación, tales como logging, debugging, seguridad, validación de sesiones, etc. Poner el código para hacer estas tareas en los servlets conlleva muchimas desventajas:

1. El código se repite en todos los servlets (problemas copy-paste!)

2.  Coupling entre el código de pre-procesamiento, el de post-procesamiento y la lógica de negocios.

Este patrón indica que estas tareas deben ser hechas a traves de filtros que se concatenan tanto en el preprocesamiento como en el post-procesamiento. Un filter manager combina estos filtros (loosely coupled) delegando el control al filtro apropiado. De esta manera se pueden agregar, remover o combinar los diferentes filtros de muchas maneras, sin alterar la lógica de negocios.

Este pattern esta contemplado en la especificación de Servlets 2.3 a través de los 'Filters'

Entonces, para sintetizar:

Escenario: tenemos que agregar una tarea común a todos los servlets, que no esta relacionado con la lógica de negocios.

Beneficios: 1. Eliminar duplicación de código. 2. Los componentes son debilmente acoplados.

[Core J2EE Patterns]

 

Front Controller

Este pattern nace de la necesidad de tener un punto de acceso único a la aplicación, que facilite el manejo de System Services, obtención de contenidos, manejo de vistas, etc. Si nos situamos dentro del pattern MVC, el 'Front Controller' es el componente que recibe los requerimientos, los forwardea a los elementos encargados de procesar la lógica y luego lo forwardea nuevamente a la vista (esta vez incluyendo los datos obtenidos). Si no tuvieramos un punto de acceso único, tendríamos los siguientes problemas:

1. Código duplicado (nuevamente)

2. Manejo no centralizado de vistas

El ejemplo más conocido de un Servlet que implementa este pattern es el ActionServlet de Struts. Este servlet se 'configura' mediante un archivo llamado servlet-config.xml que determina cuales son los 'Actions' que van a procesar el requerimiento y cuales son las vistas que serán mostradas luego de ser procesado.

**No conozco otro uso que no sea en MVC.

 

Model-View-Controller

Este pattern es una pattern de más alto nivel que los 2 anteriores. La idea de este pattern es separar completamente la lógica de negocios y la vista, uniendolos solamente a través de un Controller. Esta separación permite por ejemplo que en la vista trabajen diseñadores gráficos, mientras que la lógica esta hecha por programadores o poder cambiar la vista (de JSPs a XSLT) sin que esto conlleve ningun cambio en la lógica, es decir en el modelo.

En este pattern tenemos 3 componentes:

El modelo: Formado por los objetos de negocios (POJOS o EJBs)

La vista: Es la encargada de mostrar los datos (primero de los forms iniciales y luego de los resultados obtenidos)(JSPs, XSLT, etc.)

El Controller: es el encargado de determinar en base al requerimiento cuales son los objetos que procesarán el requerimiento y luego de forwardear a la vista que corresponda los resultados (generalmente es un servlet, configurado a través de un XML o de un property file)

Este pattern se utiliza en todas las aplicaciones desde medianamente complejas hacia adelante (por un par de páginas, el overhead es demasiado)

 

La clásica imagen del tutorial de J2EE

 

Business Delegate

La idea de este patrón es intentar disminuir la complejidad que tiene acceder a componentes de negocios remotos. Los problemas que surgen son de 3 tipos:

1. La interfase del componente puede cambiar, por lo que el cliente también deberá hacerlo (esto reduce la flexibilidad)

2. Cuando un cliente interactúa directamente con un componente de negocios remoto, esto puede requerir muchas invocaciones. Si a esto le sumamos que las invocaciones son remotas, los problemas son muchos mayores.

3. El 3er problema es toda la infraestructura con la que el cliente tiene que lidiar para acceder directamente a componentes remotos (JNDI, lidiar con los errores, etc.)

El 'business delegate' es una abstracción de la capa de negocios en el cliente que esconde los detalles 'sucios' de la interacción con objetos remotos, es decir se encarga de obtener los EJBs mediante JNDI, se encarga de instanciarlos, se encarga de lidiar con las excepciones remotas que para el cliente no tienen sentido transformandolas en excepciones de aplicación, se encarga de tratar nuevamente en el caso que esto ayude y hasta puede actuar como un cache (para no tener que obtener el EJB handle nuevamente por ejemplo)

** El cliente puede estar en el web container y llama a un objeto del EJB container (dentro de la misma JVM) o puede ser un cliente remoto realmente. El pattern se aplica en ambos casos.

Service Locator

La idea de este patrón es encapsular toda la lógica requerida para hacer lookups en servicios remotos (JNDI) en un componente. Además, este componente puede ser usado como un caché de las referencias remotas obtenidas (ya que el mecanismo de lookup puede ser bastante caro).

 

Transfer Object

La idea de este patrón es evitar 'muchos' llamados remotos (chatty calls) agrupando todos los datos que se quieren obtener en un JavaBean (el transfer object). Luego el cliente podrá obtener todos los datos que necesite haciendo llamadas a getters locales. El  beneficio de este patrón es que se elimina el overhead dado por las multiples llamada a través de la red, reduciendola a 1 llamada (que obviamente mandará un objeto mucho más grande). Obviamente, este javabean debe ser serializable (para poder ser mandado remotamente).