Catálogo de Patrones de Diseño J2EE. I.- Capa de Presentación

El mecanismo de manejo de peticiones de la capa de presentaci�n debe controlar y coordinar el procesamiento de todos los usuarios a trav�s de varias peticiones. Dichos mecanismos de control se pueden manejar de una forma centralizada o descentralizada.

.�Problema

El sistema requiere un punto de acceso centralizado para que el manejo de peticiones de la capa de presentaci�n soporte la integraci�n de los servicios del sistema, recuperaci�n de contenidos, control de vistas, y navegaci�n. Cuando el usuario accede a la vista directamente sin pasar un mecanismo centralizado, podr�an ocurrir dos problemas:

  • Se requiere que cada vista proporcione sus propios servicios del sistema, lo que normalmente resulta en duplicaci�n de c�digo.
  • La vista de navegaci�n se deja a los visores. Esto podr�a resultar en una mezcla de contenidos y navegaci�n.

Adem�s, el control distribuido es m�s dif�cil de mantener, ya que los cambios se tienen que realizar en numerosos lugares.

.�Causas

  • El procesamiento de servicios del sistema comunes se completa por cada petici�n. Por ejemplo, el servicio de seguridad completa los chequeos de autentificaci�n y autorizaci�n.
  • La l�gica se maneja mejor en una localizaci�n central en lugar de estar replicada dentro de varias vistas.
  • Existen puntos de decisi�n con respecto a la recuperaci�n y manipulaci�n de los datos.
  • Se utilizan varias vistas para responder a peticiones de negocio similares.
  • Puede ser muy �til un punto de contacto centralizado para manejar una petici�n, por ejemplo, para controlar y grabar el camino de un usuario por la site.
  • Los servicios del sistema y la l�gica de control de vistas son relativamente sofisticados.

.�Soluci�n

Usar un controlador como el punto inicial de contacto para manejar las peticiones. El controlador maneja el control de peticiones, incluyendo la invocaci�n de los servicios de seguridad como la autentificaci�n y autorizaci�n, delegar el procesamiento de negocio, controlar la elecci�n de una vista apropiada, el manejo de errores, y el control de la selecci�n de estrategias de creaci�n de contenido.

El controlador proporciona un punto de entrada centralizado que controla y maneja las peticiones Web. Centralizando los puntos de decisi�n y control, el controlador tambi�n ayuda a reducir la cantidad de c�digo Java, llamadas a scriptles, embebidos en la p�gina JavaServer Pages (JSP).

Centralizar el control en el controlador y reduciendo la l�gica de negocios en la vista permite reutilizar el c�digo entre peticiones. Es una aproximaci�n preferible a la alternativa de embeber c�digo en varias vistas porque esta aproximaci�n trata con entornos m�s propensos a errores, y de reutilizaci�n del tipo copiar-y-pegar.

T�picamente, un controlador se coordina con un componente dispatcher. Los dispatchers son responsable del control de la vista y de la navegaci�n. As�, un dispatcher elige la siguiente vista por el usuario y dirige el control al recurso. Los dispatchers podr�an encapsularse directametne dentro del controlador o se puede extraer en un componente separado.

Aunque el patr�n Front Controller sugiere la centralizaci�n del manejo de peticiones, no limita el n�mero de manejadores en el sistema, como lo hace Singleton. Una aplicaci�n podr�a utilizar varios controladores en un sistema, cada uno mapeado a un conjunto de servicios distintos.

.�Estructura

La siguiente figura representa el diagrama de clases del patr�n Front Controller.

.�Participantes y Responsabilidades

La siguiente figura representa el diagrama de la secuencia del patr�n Front Controller. Muestra como el controlador maneja una petici�n:

.�Controller

El controlador es el punto de contacto inicial para manejar todas las peticiones en el sistema. El controlador podr�a delegar a un helper para completar la autentificaci�n y la autorizaci�n de un usuario o para iniciar la recuperaci�n de un contacto.

.�Dispatcher

Un dispatcher es el responsable del manejo de la vista y de la navegaci�n, controlando la elecci�n de la siguiente vista que se le presentar� al usuario, y proporcionando el mecanismo para dirigir el control a ese recurso.

Un dispatcher se puede encapsular dentro de un controlador o se puede separar en otro componente que trabaja de forma coordinada. El dispatcher puede proporcionar un re-env�o est�tico de la vista o un mecanismo de re-env�o m�s sofisticado.

El dispatcher utiliza un objeto RequestDispatcher (soportado en la especificaci�n Servlet) y encapsula alg�n procesamiento adicional.

.�Helper

Un helper es el responsable de ayudar a la vista o al controlador a completar su procesamiento. As�, los helpers tienen muchas responsabilidades, incluyendo la recopilaci�n de los datos requeridos por la vista y el almacenamiento en el modelo intermedio, en cuyo caso algunas veces nos podemos referir al helper como un bean de valor. Adem�s, los helpers pueden adaptar este modelo de datos para usarlo en la vista.

Una vista podr�a trabajar con cualquier n�mero de helpers, que normalmente son componentes JavaBeans (JSP 1.0+) y etiquetas personalizadas (JSP 1.1+). Adem�s, un helper podr�a representar un objeto Command o un Transformador XSL, que se utiliza en combinaci�n con una hoja de estilos para adaptar y convertir el modelo a la forma apropiada.

.�View

Una Vista representa y muestra informaci�n al cliente. La vista recupera informaci�n desde el modelo. Los helpers soportan las diferentes vistas encapsulando y adaptanto el modelo de datos subyacente para usarlo en el display.

.�Estrategias

Hay varias estrategias para implementar un controlador.

.�Servlet Front

La estrategia de Servlet Frontal sugiere la implementaci�n del controlador como un servlet. Aunque sem�nticamente equivalente, es mejor que la Estrategia de JSP Frontal. El controlador maneja los aspectos del manejo de peticiones que est�n relacionados con el procesamiento de negocio y el control de flujo. Estas responsabilidades est�n relacionadas con, pero son l�gicamente independientes, del formateo de display, y es m�s apropiado encapsularlas en un servlet en lugar de en una p�gina JSP.

Esta estrategia tiene algunos potenciales inconvenientes. En particular, no permite utilizar algunas de las utilidadess del entorno de ejecuci�n JSP, como es el relleno autom�tico de par�metros de la peticion. Afortunadamente, este inconveniente es m�nimo porque es relativamente f�cil crear u obtener utilidades similares para su uso general. Abajo podemos ver un ejemplo de la Estrategia Servlet Front:


public class EmployeeController extends HttpServlet {
  // Initializes the servlet.
  public void init(ServletConfig config) throws 
    ServletException {
    super.init(config);
  }

  // Destroys the servlet.
  public void destroy() {
  }

  /** Processes requests for both HTTP  
   * <code>GET</code> and <code>POST</code> methods.
   * @param request servlet request
   * @param response servlet response
   */
  protected void processRequest(HttpServletRequest 
    request, HttpServletResponse response)
    throws ServletException, java.io.IOException {
    String page;

    /**ApplicationResources provides a simple API 
     * for retrieving constants and other 
     * preconfigured values**/
    ApplicationResources resource = 
      ApplicationResources.getInstance();
    try {

      // Use a helper object to gather parameter 
      // specific information.
      RequestHelper helper = new
         RequestHelper(request);

      Command cmdHelper= helper.getCommand();

      // Command helper perform custom operation
      page = cmdHelper.execute(request, response);

    }
    catch (Exception e) {
      LogManager.logMessage(
        "EmployeeController:exception : " + 
        e.getMessage());
      request.setAttribute(resource.getMessageAttr(),   
        "Exception occurred : " + e.getMessage());
      page = resource.getErrorPage(e);
    }
    // dispatch control to view
    dispatch(request, response, page);
  }

  /** Handles the HTTP <code>GET</code> method.
   * @param request servlet request
   * @param response servlet response
   */
  protected void doGet(HttpServletRequest request, 
    HttpServletResponse response)
    throws ServletException, java.io.IOException {
      processRequest(request, response);
  }

  /** Handles the HTTP <code>POST</code> method.
   * @param request servlet request
   * @param response servlet response
   */
  protected void doPost(HttpServletRequest request, 
    HttpServletResponse response)
    throws ServletException, java.io.IOException {
        processRequest(request, response);
  }

  /** Returns a short description of the servlet */
  public String getServletInfo() {
    return "Front Controller Pattern" + 
      " Servlet Front Strategy Example";
  }

  protected void dispatch(HttpServletRequest request, 
    HttpServletResponse response,
    String page) 
  throws  javax.servlet.ServletException, 
    java.io.IOException {
    RequestDispatcher dispatcher = 
      getServletContext().getRequestDispatcher(page);
    dispatcher.forward(request, response);
  }
}

.�JSP Front

La estrategia de JSP Frontal sugiere la implementaci�n del controlador como una p�gina JSP. Aunque sem�nticamente equivalente, es mejor utilizar la Estrategia de Servlet Frontal. Como el controlador maneja el procesamiento que no est� especificamente relacionado con el formateo de la salida, no tiene sentido implementar este componente como una p�gina JSP.

La implementaci�n del controlador como una p�gina JSP tiene otra raz�n para no ser la preferida: Requiere que un desarrollador de software trabaje con una p�gina de etiquetas para poder modificar la l�gica del control de peticiones. El siguiente listado es un ejemplo de esta estrategia:


<%@page contentType="text/html"%>
<%@ page import="corepatterns.util.*" %>
<html>
<head><title>JSP Front Controller</title></head>
<body>

<h3><center> Employee Profile </h3>

<%
/**Control logic goes here...
  At some point in this code block we retrieve 
  employee information, encapsulate it within a value 
  object and place this bean in request scope with the 
  key "employee". This code has been omitted.

  We either dispatch to another JSP at this point or 
  simply allow the remaining portions of scriptlet 
  code to execute**/
%>
  <jsp:useBean id="employee" scope="request" 
    class="corepatterns.util.EmployeeTO"/>
<FORM method=POST >
<table width="60%">
<tr>
    <td>  First Name : </td>
<td>  <input type="text" 
        name="<%=Constants.FLD_FIRSTNAME%>" 
        value="<jsp:getProperty name="employee" 
        property="firstName"/>"> </td>
</tr>
<tr>
    <td>  Last Name : </td>
    <td>    <input type="text" 
        name="<%=Constants.FLD_LASTNAME%>"  
        value="<jsp:getProperty name="employee" 
        property="lastName"/>"></td>
</tr>
<tr>
    <td>  Employee ID : </td>
    <td>    <input type="text" 
        name="<%=Constants.FLD_EMPID%>" 
        value="<jsp:getProperty name="employee" 
        property="id"/>"> </td>
</tr>
<tr>
    <td>    <input type="submit" 
        name="employee_profile"> </td>
    <td> </td>
</tr>
</table>
</FORM>

</body>
</html>

.�Command and Controller

Basada en el patr�n Commando de [GoF], la estrategia de Commando y Controlador sugiere proporcionar un interface gen�rico para los componentes helper en los que el controlador podr�a delegar responsabilidades, minimizando el acoplamiento entre estos componentes. A�adir o modificar el trabajo que necesitan realizar estos helpers no requiere ning�n cambio en el interface entre el controlador y ellos, sino en el tipo y/o contenido de los comandos. Esto proporciona un mecanismo flexible y f�cilmente extensible para que los desarrolladores puedan a�adir comportamientos al manejo de peticiones.

Finalmente, como el procesamiento de comandos no est� acoplado a la invocaci�n de comandos, el mecanismo de procesamiento de comandos se podr�a reutilizar para varios tipos de clientes, no s�lo con los navegadores Web. Esta estrategia tambi�n facilita la creaci�n de comandos compuestos. Aqu� tenemos un ejemplo de esta estrategia:

 

/** This processRequest method is invoked from both 
  * the servlet doGet and doPost methods **/
protected void processRequest(HttpServletRequest 
  request, HttpServletResponse response)
  throws ServletException, java.io.IOException {

  String resultPage;
  try {
    RequestHelper helper = new RequestHelper(request);

    /** the getCommand() method internally uses a 
     factory to retrieve command objects as follows:
     Command command = CommandFactory.create(
        request.getParameter("op"));
    **/
     Command command =  helper.getCommand();
 
    // delegate request to a command object helper
    resultPage = command.execute(request, response);
  }
  catch (Exception e) {
    LogManager.logMessage("EmployeeController",
      e.getMessage() );
    resultPage = ApplicationResources.getInstance().
                      getErrorPage(e);
  }

  dispatch(request, response, resultPage);
}

En la siguiente figura podemos ver el diagrama de secuencia de la estrategia Command and Controller.

.�Phisical Resource Mappping

En la estrategia de Mapeo F�sico de Recursos todas las peticiones se hacen sobre nombres de recursos f�sicos especificos en lugar de sobre nombres l�gicos. Un ejemplo es la siguiente URL: http://some.server.com/resource1.jsp. En el caso de un controlador, un ejemplo de URL podr�a ser: http://some.server.com/servlet/Controller. Es preferible utilizar la estrategia de Mapeo L�gico de Recursos porque proporciona una mayor flexibilidad, porque nos permite mapear los recuros de una forma declarativa.

.�Logical Resource Mapping

En la estrategia de Mapeo de Recurso L�gico todas las peticiones se hacen sobre nombres de recursos l�gicos en vez de sobre nombres f�sicos espec�ficos. Los recursos f�sicos a los que se refieren estos nombres l�gicos podr�an modificarse de una forma declarativa.

Por ejemplo, la URL http://some.server.com/process podr�a mapearse como:

process=resource1.jsp

o como:

process=resource2.jsp

o como:

process=servletController
.�Multiplexed Resource Mapping

La estrategia de Mapeo Multiplexado de Recursos realmente es una estrategia de Mapeo L�gico de Recursos. Esta estrategia no mapea s�lo a un nombre l�gico, sino a un conjunto completo de nombres l�gicos, para un s�lo recurso f�sico. Por ejemplo, un mapeo de comod�n podr�a mapear todas las peticiones que terminen en .ctrl a un controlador espec�fico, como podermos ver en la siguiente tabla:

Petici�n> Mapeo
http://some.server.com/action.ctrl *.ctrl = servletController

De hecho, es la estragegia que utilizan los motores de p�ginas JSP para asegurarse de que las peticiones de recursos de p�ginas JSP (es decir, recursos cuyos nombres terminan en .jsp) las procesa el manejador apropiado.

Se pueden a�adir informaci�n adicional a una peticion, proporcionando mayores detalles para este mapeo l�gico, como se puede ver en la siguiente tabla:

Petici�n> Mapeo
http://some.server.com/profile.ctrl?usecase= create *.ctrl = servletController

Un beneficio importante de la utilizaci�n de esta estrategia es que proporciona una enorme flexibilidad cuando dise�anos nuestros componentes de manejo de peticiones. Cuando se combina con las otras estrategias, como con la estrategia Command and Controller, se pueden crear un potente marco de trabajo para manejar peticiones.

Consideremos un controlador que maneja todas las peticiones que terminan en .ctrl, como hemos visto antes. Consideremos tambi�n la parte izquierda del nombre de recursos delimitado por puntos (profile en el ejemplo de arriba) para que sea una parte del nombre de un ejemplo. Ahora combinamos este nombre con el valor de par�metro de la consulta (creado en el ejemplo de arriba). Estamos diciendo a nuestos manejador de peticiones que queremos procesar un ejemplo llamado crear perfil. Nuestro mapeo de recursos multiplexado env�a la petici�n a nuestro servletController, que es parte del mapeo mostrado en la tabla anterior. Nuestro controlador crea el objeto command apropiado, seg�n describimos en la Estrategia Command and Controller. �C�mo sabe el controlador en qu� objeto command deber�a delegar? Utilizando la informaci�n adicional de la URI de la petici�n, el controlador delega en el objeto command que maneja la creaci�n de perfiles. Est� podr�a ser un objeto ProfileCommand que sirve peticiones para la creaci�n y modificaci�n de perfiles, o podr�a ser un objeto m�s espec�fico como ProfileCreationCommand.

.�Dispatcher in Controller

Cuando la funcionalidad del dispatcher es m�nima, se puede plegar junto al controlador, como se muestra en la siguiente figura:

.�Base Front

La estrategia Base Front utilizada en combinaci�n con la estrategia Servlet Front, sugiere la implementaci�n de una clase base controladora, cuya implementaci�n deben extender otros controladoes. La clase Base Front podr�a contener implementaciones comunes y por defecto, aunque las subclases puedan sobreescribir estas implementaciones. El inconviente de esta estrategia es el hecho de que un superclase compartida, aunque promueve la reutilizaci�n y la compartici�n, tiene el problema de crear un herencia fr�gil, donde los cambios necesarios para una subclase afectan a todas las dem�s subclases.

.�Filter Controller

Los filtros proporcionan un soporte similar para la centralizaci�n de manejo de peticiones. As�, algunos aspectos de un controlador se pueden implementar de forma razonable como un filtro. Al mismo tiempo, los filtros se enfocan principalmente en la intercepci�n y decoraci�n de peticiones, no en el procesamiento y en la generaci�n de respuestas. Aunque hay un solapamietno de responsabilidades, como en el manejo del log y la depuraci�n, cada componente complementa a los otros cuando se utilizan de la forma apropiada.

.�Consecuencias

  • Centraliza el Control
    Un controlador proporciona un lugar central para manejar los servicios del sistema y la l�gica de negocios entre varias peticiones. Un controlador maneja el procesamiento de la l�gica de negocio y el manejo de peticiones. El acceso centralizado a una aplicaci�n significa que las peticiones se pueden seguir y guardar muy f�cilmente. Debemos tener en mente, que como controles centralizados, es posible presentar un s�lo punto de fallo. En la pr�ctica, esto r�ramente es un problema, ya que t�picamente existe m�ltiples controladores, bien dentro de un s�lo servidor o en un cluster.
  • Mejora la Manejabilidad de la Seguridad
    Un controlador centraliza el control, propocionando un punto de choque para intentos de accesos il�citos en la aplicaci�n Web. Adem�s, auditar una sola entrada en la aplicaci�n requiere menos recursos que distribuir los chequeos de seguridad entre todas las p�ginas.
  • Mejora la Reutilizabilidad
    Un controlador promueve el particionamiento limpio de la aplicaci�n y aconseja la reutilizaci�n, ya que el c�digo que es com�n entre los componentes se mueve dentro de un controlador o es manejado por un controlador.

.�Patrones Relacionados

  • View Helper
    El patr�n Front Controller, en conjunci�n con el patr�n View Helper, describe la creaci�n de l�gica de negocio de la vista y proporciona un punto central de control y reenvio. El flujo l�gico se construye dentro del controlador y el c�digo de manejo de datos se mueve hacia los helpers.
  • Intercepting Filter
    Tanto Intercepting Filter como Front Controller describen formas de centralizar el control de ciertos tipos de procesamiento de peticiones, sugiriendo diferentes aproximaciones a este problema.
  • Dispatcher View y Service to Worker
    Los patrones Dispatcher View y Service to Worker son otras forma de nombrar la combinaci�n entre el patr�n View Helper con un dispatcher, y un patr�n Front Controller. Dispatcher View y Service to Worker, aunque estructuralmente son iguales, describen diferentes divisiones de labores entre los componentes.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO