Programación en castellano
Inicio > Tutoriales > J2EE > Catálogo de Patrones de Diseño J2EE. I.- Capa de Presentación
-Tutoriales

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


Front Controller

. Contexto

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.
 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: musica mp3 | logos y melodias | hospedaje web linux | registro de dominios | servidores dedicados
más internet: comprar | recursos gratis | posicionamiento en buscadores | tienda virtual | gifs animados