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

El sistema controla el flujo de ejecuci�n y accede al proceso de presentaci�n, que es el responsable de generar el el contenido din�mico.

Nota:
El patr�n Dispatcher View, igual que el patr�n Service to Worker, describe una combinaci�n com�n de otros patrones del cat�logo. Estos dos macro-patrones describen la combinaci�n de un controlador y un dispatcher con vistas y helpers. Aunque describen esta estructura com�n, cada uno enfatiza un uso diferente de los patrones.

.�Problema

El problema es una combinaci�n de los problemas resueltos por los patrones Front Controller y View Helper de la capa de presentaci�n. No hay un componente centralizado para manejar el control de acceso, la recuperaci�n de contenido, o el manejo de la vista, y hay c�digo de control duplicado esparcido por varias vistas. Adem�s, la l�gica de negocio y la de formateo de la presentaci�n est�n mezcladas en esas vistas, haciendo que el sistema sea menos flexible, menos reutilizable y generalmente menos resistente a los cambios.

Mezclar l�gica de negocio con el procesamiento de la vista tambi�n reduce la modularidad y proporciona una pobre separaci�n de roles entre los equipos de producci�n Web y de desarrollo de software.

.�Causas

  • Los chequeos de autentificaci�n y autorizaci�n se completan en cada petici�n.
  • El c�digo scriptlet dentro de las vistas se deber�a minimizar.
  • La l�gica de negocio se deber�a encapsular en componentes distintos a la vista.
  • El control de flujo es relativamente complejo y se basa en valores del contenido din�mico.
  • La l�gica de control de la vista es relativamente sofisticada, con varias vistas que potencialmente se mapean a la misma petici�n.

.�Soluci�n

Combinar un controlador y un dispatcher con vistas y helpers (ver Front Controller y View Helper) para manejar peticiones de clientes y preparar una presentaci�n din�mica como respuesta. Los controladores delegan la recuperaci�n de contenido en los helpers, que manejan el relleno del modelo intermedio para la vista. Un dispatcher es el responsable del control de la vista y la navegaci�n y puede encapsularse dentro de un controlador o de un componente separado.

Dispatcher View describe la combinaci�n de los patrones Front Controller y View Helper con un componente dispatcher. Aunque este patr�n y Service to Worker describen una estructura similar, ambos sugieren diferentes divisiones de la labor entre los componentes. El controlador y el dispatcher tienen responsabilidades limitadas, comparadas con el patr�n Service to Worker, porque la l�gica de procesamiento y de control de vista son b�sicas. Adem�s, si no se considera necesario el control de los recursos subyacentes, se puede eliminar el controlador y el dispatcher se podr�a mover dentro de una vista.

Aunque los patrones Service to Worker y Dispatcher View representan una combinaci�n de otros patrones del cat�logo, el primero garantiza con su nombre una comunicaci�n eficiente entre los desarrolladores. Mientras que el segundo sugiere una recuperaci�n de contenido relegada al momento de procesamiento de la vista.

En el patr�n Dispatcher View, el dispatcher normalmente juega un rol moderado en el control de la vista. En el patr�n Service to Worker, el dispatcher juega un rol algo m�s elevado en el control de la vista.

Un rol limitado para el dispatcher ocurre cuando no se utilizan recursos exteriores para poder elegir la vista. La informaci�n encapsulada en la petici�n es suficiente para determinar la vista a la que despachar la petici�n. Por ejemplo:

http://some.server.com/servlet/Controller?next=login.jsp

La �nica responsabilidad del componente dispatcher en este caso es reenviar a la vista login.jsp.

Un ejemplo del dispatcher jugando un rol moderado es el caso donde el cliente env�a una petici�n directamente al controlador con un par�metro de consulta que describe una acci�n a realizar:

http://some.server.com/servlet/Controller?action=login

Aqu� la responsabilidad del dispatcher es traducir el nombre l�gico login en el nombre del recurso de una vista apropiada, como login.jsp, y reenviar a esa vista. Para conseguir esta traducci�n, el dispatcher podr�a acceder a recursos como un fichero de configuraci�n XML que especifica las vistas apropiadas a mostrar.

Por otro lado, en el patr�n Service to Worker, el dispatcher podr�a invocar servicios de negocio para determinar la vista apropiada que se debe mostrar.

La estructrua compartida de Service to Worker y Dispatcher View consiste en un controlador trabajanado con un dispatcher, vistas y helpers.

.�Estructura

En la siguiente figura podemos ver el diagrama de clases que representa al patr�n Dispatcher View.

.�Participantes y Responsabilidades

La siguiente figura muestra el diagrama de secuencia que representa al patr�n Dispatcher View.

Aunque las responsabilidades del controlador est�n limitadas a los servicios del sistema, como la autentificaci�n y autorizaci�n, todav�a es beneficioso centralizar estos aspectos del sistema. Observa tambi�n que, al contrario que el patr�n Service to Worker, el dispatcher no hace llamadas a servicios de negocio para poder completar el procesamiento de la vista.

La funcionalidad del dispatcer se podr�a encapsular en su propio componente. Al mismo tiempo, cuando las responsabilidades del dispatcher son limitadas, como se describen en este patr�n, la funcionalidad del dispatcher se puede poner en otro componente, como en el controlador o la vista.

De hecho, la funcionalidad del dispatcher podr�a incluso ser completada por el contenedor, en el caso donde no sea necesaria una l�gica extra a nivel de la aplicaci�n. Un ejemplo es una vista llamada main.jsp a la que se le da el alias de first. El contenedor procesar� la siguiente petici�n, traduciendo el nombre del alias al nombre del recurso f�sico, y reenviando directamente a ese recurso:

http://some.server.com/first --> /mywebapp/main.jsp

En este caso, nos hemos quedado con el patr�n View Helper, donde la petici�n la maneja directamente la vista. Como la vista es el punto de contacto inicial para manejar peticiones, normalmente se utilizan etiquetas personalizadas para realizar el procesamiento de negocio o para delegar este procesamiento a otros componentes.

As�, el patr�n Dispatcher View describe una continuidad de escenarios relacionados, movi�ndose de un escenario que es estructuralmente similar a Service to Worker a otro que es similar a View Helper.

.�Controller

El controlador normalmente es el punto de contacto inicial para manejar una petici�n. El controlador maneja la autentificaci�n y la autorizaci�n, y delega en un dispatcher para hacer el control de la vista.

.�Dispatcher

Un dispatcher es el responsable del control de la vista y la navegaci�n, controlando la elecci�n de la siguiente vista a mostrar y proporciona el mecanismo para dirigir el control a este recurso.

Un dispatcher se puede encapsular dentro de un controlador (ver Front Controller) o puede ser un componente independiente que trabaja en coordinaci�n con el controlador. El dispatcher puede proporcionar reenv�o est�tico a la vista o podr�a proporcionar un mecanismo de reenv�o din�mico m�s sofisticado.

.�View

Una Vista representa una presentaci�n de informaci�n al cliente. La informaci�n utilizada en esta presentaci�n se recupera de un modelo. Los helpers soportan vistas encapsulando y adaptando un modelo para utilizarlo en una presentaci�n.

.�Helper

Un helper es el responsable de ayudar a la vista o al controlador a completar su procesamiento. As�, los helpers tienen numerosas responsabilidades, incluyendo la obtenci�n de los datos requeridos por la vista y almacen�ndolos en el modelo intermedio, en cuyo caso el helper es conocido como un value bean. Adem�s, los helpers podr�an adaptar este modelo de datos para que los utilice la vista. Los helpers pueden servir peticiones de datos desde la vista simplemente proporcionando acceso a los datos en bruto o formate�ndolos como contenido Web.

Una vista podr�a trabajar con cualquier n�mero de helpers, que normalmente est�n implementados por componentes JavaBeans (JSP 1.0+) o componentes de etiquetas personalidas (JSP 1.1+). Adem�s, un helper podr�a representar un objeto Command o delegate.

.�ValueBean

Un value bean es otro nombre para un helper que es responsable de contener el estado del modelo intermedio para que lo utilice una vista.

.�BusinessService

Servicio de Negocio es un rol que cumple el servicio al que el cliente quiere acceder. Normalmente, se accede al servicio de negocio mediante un Business delegate. El rol del business delegate es proporcionar control y protecci�n para el servicio de negocio (puedes ver el patr�n "Business Delegate" m�s adelante).

.�Estrategias

.�Servlet Front

Ver la estrategia "Servlet Front" en el patr�n Front Controller.

.�JSP Front

Ver la estrategia "JSP Front" en el patr�n Front Controller.

.�JSP page View

Ver la estrategia "JSP page View" en el patr�n View Helper.

.�Servlet View

Ver la estrategia "Servlet View" en el patr�n View Helper.

.�JavaBean Helper

Ver la estrategia "JavaBean Helper" en el patr�n View Helper.

.�Custom Tag Helper

Ver la estrategia "Custom Tag Helper" en el patr�n View Helper.

.�Dispatcher in Controller

Ver la estrategia "Dispatcher en Controller" en el patr�n Front Controller.

Como hemos visto, los patrones Service to Worker y Dispatcher View sugieren una continuidad, donde el comportamiento se ha encapsulado m�s cerca de la vista o se ha movido hac�a atr�s en el flujo de proceso. La siguiente figura muestra las interacciones para esta estrategia:

El controlador no crea explicit�mente un objeto dispatcher. En vez de eso, el controlar tiene cuidado de reenviar a la vista. Alternativamente, se podr�a implementar un dispatcher en el que el controldor puede delegar la funci�n de reenv�o.

.�Dispatcher in View

Si el controlador se eliminara debido a su rol limitado, el dispatcher se podr�a mover a una vista. Este dise�o puede ser �til en casos donde es t�pico que una vista mapee a una petici�n espec�fica, pero donde se podr�a utilizar de forma poco frecuente un vista secundaria. Por ejemplo, bas�ndose en la informaci�n de la petici�n o los resultados de alg�n procesamiento de la vista, un helper de etiqueta personalizada en la vista podr�a dirigir el control a una vista secundaria. Un caso t�pico es cuando una petici�n de cliente es reenviada a una vista espec�fica, y ser� servida por esa vista en cualquier otro caso.

Consideremos el caso donde el usuario no se ha autentificado, pero pide acceso a unas p�ginas JSP protegidas de la site. Como la site tiene s�lo unas pocas p�ginas JSP protegidas, y el contenido din�mico es limitado, la autentificaci�n se puede realizar dentro de esas p�ginas JSP, en lugar de utilizar un controlador centralizado para toda la site. Esas p�ginas que necesitan autentificacion incluyen un helper de etiqueta personalizada al principio de la p�gina. Este helper realiza el chequeo de autentificaci�n y muestra la p�gina al usuario o lo reenv�a a la p�gina de autentificaci�n. La siguiente figura representa este escenario:

.�Transformer Helper

Ver la estrategia "Transformer Helper" en el patr�n View Helper.

.�Consecuencias

  • Centraliza el Control y Mejora la Modularidad y la Reutilizaci�n
    Este patr�n sugiere proporcionar un lugar central para manejar los servicios del sistema y la l�gica de negocio entre varias peticiones. El contolador maneja el procesamiento de la l�gica de negocio y el manejo de peticiones. Hay que tener en cuenta, que como control centralizado, es posible introducir un s�lo unto de fallo.
  • Mejora el Particionamiento de la Aplicaci�n
    La utilizaci�n de helpers resulta en una separaci�n clara entre la vista y el procesamiento de negocio en una aplicaci�n. Los helpers, en la forma de JavaBeans (JSP 1.0+) o etiquetas personalizadas (JSP 1.1+), proporcionan un lugar donde construir la l�gica de negocio fuera de la p�gina JSP. Si la l�gica de negocio se deja dentro de la p�gina JSP, los grandes proyectos resultan embrollados.
  • Mejora la Separaci�n de Roles
    Al separar la l�gica de formateo de la l�gica de negocio de la aplicaci�n tambi�n se reducen las dependencias de los mismos recursos entre individuos que cumplen diferentes roles. Sin esta separaci�n, por ejemplo, un desarrollador de sofware poseer�a c�digo que est� embebido dentro de marcas HTML, mientras que un miembro del equipo de producci�n Web necesitar�a modificar la distribuci�n de una p�gina y dise�ar componentes que est�n mezclados con l�gica de negocio. Como ning�n individuo que cumple estos roles est� familiarizado con las implementaciones espec�ficas del trabajo del otro individuo, se puede llegar a un punto de confusi�n en que las modificaciones accidentales introduzcan errores el sistema.

.�C�digo de Ejemplo

El siguiente c�digo de ejemplo muestra una implementaci�n del patr�n Dispatcher View, utilizando un servlet controlador y una vista con helpers JavaBean y de etiquetas personalizadas. La implementaci�n incluye las estrategias Servlet Front, Dispatcher in Controller, JSP View, JavaBean Helper y Custom Tag Helper. Tambi�n utiliza una vista compuesta muy b�sica, mostrada en la siguiente imagen:

El siguiente ejemplo muestra el servlet controlador que simplemente completa el chequeo de autentificaci�n y pasa el control a la vista apropiada. Observa que el controlador no delega directamente a ning�n componente helper para poder hacer llamadas a la capa de negocio mediante Delegate. Est�s responsabilidades se han relegado a la vista, que se llama accountdetails.jsp. El c�digo de ejemplo utiliza un LogManager para guardar los mensajes.


public class Controller extends HttpServlet {

  /** 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 nextview;
    try {
      LogManager.recordStrategy(request, 
        "Dispatcher View", 
        " Servlet Front Strategy; " + 
    "JSP View Strategy; Custom tag helper Strategy");
      LogManager.logMessage(request, getSignature(), 
        "Process incoming request. ");

      // Use a helper object to gather parameter 
      // specific information.
      RequestHelper helper = new 
          RequestHelper(request, response);
      LogManager.logMessage(request, 
        getSignature(), " Authenticate user");

      Authenticator auth = new BasicAuthenticator();
      auth.authenticate(helper);

      //This is an oversimplification for the sake of 
      // simplicity. Typically, there will be a 
      // mapping from logical name to resource name at 
      // this point
      LogManager.logMessage(request, getSignature(), 
        "Getting nextview");
      nextview = request.getParameter("nextview");

      LogManager.logMessage(request, getSignature(), 
        "Dispatching to view: " + nextview);
    }
    catch (Exception e) {
      LogManager.logMessage(
        "Handle exception appropriately", 
        e.getMessage() );
      /** ApplicationResources provides a simple API 
        * for retrieving constants and other 
        * preconfigured values**/
      nextview = ApplicationResources.getInstance().
          getErrorPage(e);
    }
    dispatch(request, response, nextview);
  }

  /** 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 getSignature();
  }

  public void init(ServletConfig config) throws 
    ServletException {
    super.init(config);
  }

  public void destroy() { }

  /**
    * dispatcher method
    */
  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);
  }

  private String getSignature()  {
    return "DispatcherView-Controller"; 
  }
}

Observa que la vista utiliza helpers de etiquetas personalizadas para controlar la recuperaci�n de contenido. ya que esta actividad no se realiz� en el controlador. Cuando se utilizan las etiquetas personalizadas de esta forma, normalmente se convierten en estrechas fachadas para componentes solitarios en los que delegar para completar este procesamiento. De esta forma, la l�gica de procesamiento general est� pobremente acoplada a la implementaci�n de la etiqueta. Si no se utilizan etiquetas personalizadas con Dispatcher View, la p�gina JSP se terminar� llenando de c�dgio scriptlet, una situaci�n que debemos evitar.

 

<%@ taglib uri="/web-INF/corepatternstaglibrary.tld"
  prefix="corepatterns" %>

<html>
<head><title>AccountDetails</title></head>
<body>

<corepatterns:AccountQuery 
  queryParams="custid,acctkey" scope="request" />

<h2><center> Account Detail for <corepatterns:Account
  attribute="owner" /></h2> <br><br>

<tr>
  <td>Account Number :</td>
  <td><corepatterns:Account attribute="number" /></td>
</tr>

<tr>
  <td>Account Type:</td>
  <td><corepatterns:Account attribute="type" /></td>
</tr>

<tr>
  <td>Account Balance:</td>
  <td><corepatterns:Account attribute="balance" /></td>
</tr>

<tr>
 <td>OverDraft Limit:</td>
 <td><corepatterns:Account attribute="overdraftLimit" /></td>
</tr>
<table border=3>
</table>
</corepatterns:AccountQuery>

<br>
<br>

</center>
<%@ include file="/jsp/trace.jsp" %>
</body>
</html>

.�Patrones Relacionados

  • Front Controller y View Helper
    El patr�n Dispatcher View es el resultado de combinar el patr�n View Helper con un dispatcher, en coordinaci�n con el patr�n Front Controller.
  • Service to Worker
    El patr�n Service to Worker es otro nombre para la combinaci�n del patr�n Front Controller con un dispatcher, y el patr�n View Helper. Los patrones Service to Worker y Dispatcher View son id�nticos con respecto a los componentes implicados, pero son diferentes en la divisi�n de labores entre esos componentes. El patr�n Dispatcher View siguiere relegar la recuperaci�n de contenido al momento en que se procesa la vista. Adem�s, el dispatcher juega un rol m�s limitado en el control de la vista, ya que la elecci�n de le vista normalmente ya est� incluida en la petici�n.

COMPARTE ESTE ARTÍCULO

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