Catálogo de Patrones de Diseño J2EE. Y II: Capas de Negocio y de Integración

En una aplicaci�n de la plataforma J2EE, los componentes de negocio del lado del servidor se implementan utilizando beans de sesi�n, beans de entidad, DAOs, etc. Los clientes de la aplicaci�n necesitan acceder a datos que frecuentemente se componen de m�ltiples objetos.

.�Problema

Los clientes de aplicaciones normalmente solicitan los datos del modelo o parte del modelo para presentarlos al usuario o para usarlos en un paso de procesamiento intermedio antes de proporcionar alg�n servicio. El modelo de la aplicaci�n es una abstracci�n para los datos de negocio y la l�gica de negocio implementada en el lado del servidor como componentes de negocio. Un modelo se podr�a se expresar como una colecci�n de objetos que se han juntado de una manera organizada. En una aplicaci�n J2EE, el modelo es una colecci�n de objetos distribuidos como beans de sesi�n, beans de entidad, DAOs u otros objetos. Para que un cliente obtenga los datos del modelo, debe acceder individualmente a cada objeto distribuido que define el modelo. Esta aproximaci�n tiene varios inconvenientes:

  • Como el cliente debe acceder a todos los componentes distribuidos individualmente, hay un acoplamiento fuerte entre el cliente y los componentes de negocio del modelo sobre la red.
  • El cliente acede a los componentes distribuidos mediante la capa de red, y eso puede provocar una degradaci�n del rendimiento si el modelo es complejo y con n�merosos componentes distribuidos. La degradaci�n de la red y del cliente ocurre cuando el modelo de la aplicac�n implementa varios componentes de negocio distribuidos y el cliente interact�a directamente con esos componentes para obtener los datos del modelo. Todos esos accesos resultan en llamadas a m�todos remotos que sobrecargan la red e incrementan las charlataner�a entre el cliente y la capa de negocio.
  • El cliente debe reconstruir el modelo despu�s de obtener sus partes desde los componentes distribuidos. Por lo tanto, el cliente necesita tener suficiente l�gica de negocio para construir el modelo. Si la construcci�n del modelo es compleja y se ven implicados en su definici�n numerosos objetos, podr�a haber una sobrecarga adicional en el rendimiento del cliente debido al proceso de construcci�n. Adem�s, el cliente debe contener l�gica de negocio para manejar las relaciones entre los componentes, lo que resultar� en un cliente m�s complejo y todav�a m�s grande. Cuando el cliente construye el modelo de la aplicaci�n, la cosntrucci�n sucede en el lado del cliente. La construcci�n de modelos complejos podr�a resultar en una sobrecarga importante en el rendimiento del lado del cliente para clientes con recursos limitados.
  • Como el cliente est� fuertemente acoplado con el modelo, los cambios en el modelo requieren cambios en el cliente. Adem�s, si hay diferentes tipos de clientes, es m�s dif�cil manejar los cambios entre todos los tipos de cliente. Cuando hay acoplamiento fuerte entre el clente y la implementaci�n del modelo, lo que ocurre cuando el cliente tiene conocimiento directo del modelo y maneja las relaciones de los componentes de negocio, los cambios en el modelo necesitan cambios en el cliente. Adem�s, hay otro problema de duplicaci�n de c�digo para acceder al modelo, lo que ocurre cuando una aplicaci�n tiene muchos tipos de clientes. Esta duplicaci�n hace que los clientes (su c�digo) sea dif�cil de manejar cuando el modelo cambia.

.�Causas

  • Se requiere la separaci�n de la l�gica de negocio entre el cliente y los componentes del lado del servidor.
  • Como el modelo consta de componentes distribuidos, el acceso a cada componente est� asociado con un una sobrecarga de red. Es deseable minimizar el n�mero de llamadas a m�todos remotos.
  • Normalmente el cliente s�lo necesita obtener el modelo para presentarlo al usuario. Si el cliente debe interact�ar con varios componentes para construir el modelo "al vuelo", se incrementa la comunicaci�n entre el cliente y el servidor. Dicha sobrecarga de comunicaci�n podr�a reducir el rendimiento de la red.
  • Incluso si el cliente quiere realizar un actualizaci�n, normalmente s�lo actualiza ciertas partes del modelo, y no el modelo completo.
  • Los clientes no necesitan preocuparse de las intrincadas dependencias en la implementaci�n del modelo. Es deseable perder acoplamiento entre los clientes y los componentes de negocio que implementan el modelo de la aplicaci�n.
  • Los clientes no necesitan poseer la l�gica de negocio adicional requerida para construir el modelo partiendo de varios componentes de modelo.

.�Soluci�n

Utilizar un Transfer Object Assembler para construir el modelo o submodelo requerido. El Transfer Object Assembler usa Transfer Objects para recuperar los datos de los distintos objetos de negocio y otros objetos que definen el modelo o una parte del modelo.

El Transfer Object Assember construye un Transfer Object compuesto que representa los datos de diferentes componentes de negocio. El Transfer Object transporta datos del modelo al cliente en una s�la llamada a m�todo. Como los datos del modelo pueden ser complejos, se recomienda que el Transfer Object no sea modificable. Es decir, el cliente obtiene esos Transfer Objects con el �nico prop�sito de usarlos para presentaciones y procesamientos de s�lo-lectura. Si est� permitido que los clientes hagan cambios en los Transfer Objects.

Cuando el cliente necesita los datos del modelo, y si el modelo est� representado por un �nico componente gen�rico (como un Composite Entity), el proceso de obtenci�n del modelo es muy simple. El cliente simplemente solicita el componente gen�rico para su Transfer Object compuesto. Sin embargo, la mayor�a de las aplicaciones del mundo real tienen un modelo compuesto de una combinaci�n de muchos componentes gen�ricos y espec�ficos. En este caso, el cliente debe interactuar con numerosos componentes de negocio para obtener todos los datos necesarios para representar el modelo. El inconveniente inmediato de esta aproximaci�n se puede ver en que los clientes se convierte en fuertemente acoplados con la implementaci�n del modelo (elementos del modelo) y que los los clientes tienden a realizar numerosas llamadas a m�todos remotos para obtener los datos de cada componente individual.

En algunos casos, un �nico componente gen�rico proporciona el modelo o parte del modelo como �nico objeto Transfer Object (simple o compuesto). Sin embargo, cuando varios componentes representan el modelo, un �nico Transfer Object (simple o compuesto) podria no representar todo el modelo. Para representar el modelo, es necesario obtener Transfer Objects de varios componentes y ensamblarlos en un Transfer Object Compuesto. El servidor, no el cliente, deber�a realizar la construcci�n del modelo "al-vuelo".

.�Estructura

La siguiente figura muestra el diagrama de clases que representa las relaciones para el patr�n Transfer Object Assembler:

.�Participantes y Responsabilidades

El diagrama de secuencia de la siguiente figura muestra la interacci�n entre los distintos participantes en el patr�n Transfer Object Assembler:

.�TransferObjectAssembler

El TransferObjectAssembler es la clase principal de este patr�n. Construye un nuevo Transfer Object basado en los requerimientos de la aplicaci�n cuando el cliente solicita un Transfer Object compuesto. Entonces TransferObjectAssembler localiza los ojemplares BusinessObject requeridos para recuperar los datos para construir el Transfer Object compuesto. Los BusinessObjects son objetos de la capa de negocio como beans de entidad o de sesi�n, DAOs, etc.

.�Cliente

Si el TransferObjectAssembler se implementa como un objeto Java normal, el cliente normalmente es un Session Facade que proporciona la capa controladora para la capa de negocio. Si el TransferObjectAssembler se implementa como un bean de sesi�n, el cliente puede ser un Session Facade o un Business Delegate.

.�BusinessObject

BusinessObject participa en la construcci�n del nuevo Transfer Object proporcionando los datos requeridos por el TransferObjectAssembler. Por lo tanto, el BusinessObject es un rol que cumple un bean de sesi�n, un bean de entidad, un DAO, o un objeto normal de Java.

.�TransferObject

TransferObject es un Transfer Object compuesto construido por TransferObjectAssembler y devuelto al cliente. Este representa los datos complejos de varios componentes que definen el modelo de la aplicaci�n.

.�BusinessObject

BusinessObject es un rol que pueden cumplir un bean de sesi�n, un bean de entidad, o un DAO. Cuando el ensamblador necesita obtener los datos directamente desde el almacenamiento persistente, para construir el Transfer Object, puede utilizar un DAO. Esto se puede ver en los diagramas como el objeto DataAccessObject.

.�Estrategias

Esta secci�n explica las diferentes estrategias para implementar el patr�n Transfer Object Assembler.

.�Java Object

El TransferObjectAssembler puede ser un objeto normal de Java y no necesariamente un bean enterprise. En dichas implementaciones, se sit�a enfrente del TransferObjectAssembler un bean de sesi�n. Este bean de sesi�n normalmente es un Session Facade que realiza otras tareas relacionadas con proporcionar servicios de negocio. El TransferObjectAssembler se ejecuta en la capa de negocio, sin importar las estrategias de implementaci�n. La motivaci�n para esto es evitar las llamadas remotas desde el TransferObjectAssembler hacia los objetos fuente sin cruzar de capa.

.�Session Bean

Esta estrategia implementa el TransferObjectAssembler como un bean de sesi�n. Si se prefiere la implementaci�n de un bean de sesi�n para proporcionar el TransferObjectAssembler como un servicio de negocio, normalmente se implementa como un bean de sesi�n sin estado. Los componentes de negocio que componen el modelo de la aplicaci�n est�n constantemente implicados en transaciones con otros clientes. Como resultado, cuando un TransferObjectAssembler construye un nuevo Transfer Object desde varios componentes de negocio, produce una "foto" del modelo en el momento de la construcci�n. El modelo podr�a cambiar inmediatamente despu�s si otro cliente modifica uno o m�s de sus componentes de negocio, cambiando efectivamente el modelo de negocio de la aplicaci�n.

Por lo tanto, implementar TransferObjectAssembler como un bean de sesi�n con estado no proporciona ning�n beneficio sobre su implementaci�n como un bean de sesi�n sin estado, ya que es in�til preservar el estado del modelo compuesto cuando est� cambiando el modelo subyacente. Si cambia �ste modelo, hace que el Transfer Object contenido por el Assembler sea obsoleto. Cuando luego se le pide al TransferObjectAssembler, el Transfer Object, o devuelve un estado obsoleto o reconstruye el Transfer Object para obtener una imagen m�s reciente. Por lo tanto, se recomienda que el Assembler sea un bean de sesi�n sin estado.

Sin embargo, si el modelo subyacente no cambia o lo hace muy raramente, el ensamblador podr�a ser un bean de sesi�n con estado para retener el Transfer Object recientemente construido. En este caso, el TransferObjectAssembler debe incluir mecanismos para reconocer los cambios en el modelo subyacente y reconstruir el modelo para la pr�xima petici�n del cliente.

.�Business Object

Existen diferentes objetos que pueden soportar el rol del BusinessObject

  • Puede ser un bean de sesi�n. El Transfer Object Assembler podr�a utilizar un Service Locator para localizar el bean de sesi�n requerido. El Transfer Object Assembler le pide a este bean de sesi�n que le proporcione los datos para construir el Transfer Object compuesto.
  • El BusinessObject tambi�n puede ser un bean de entidad. El Transfer Object Assembler podr�a utilizar un Service Locator para localizar el bean de entidad requerido. El Transfer Object Assembler le pide a este bean de entidad que le proporcione los datos para construir el Transfer Object compuesto.
  • O puede se run DAO. El Transfer Object Assembler le pide a este DAO que le proporcione los datos para construir el Transfer Object compuesto.
  • Tambi�n puede ser un objeto Java normal. El Transfer Object Assembler le pide a este objeto Java que le proporcione los datos para construir el Transfer Object compuesto.
  • Por �ltimo, el BusinessObject puede ser otro Transfer Object Assembler. El primer Transfer Object Assembler le pide al segundo Transfer Object Assembler que le proporcione los datos para construir el Transfer Object compuesto.

.�Consecuencias

  • Independiza la L�gica de Negocio
    Cuando el cliente incluye l�gica para manejar las interacciones con componentes distribuidos, es m�s d�ficil separar claramente la l�gica de negocio de la capa de cliente. El Transfer Object Assembler contiene la l�gica de negocio para mantener las relaciones entre objetos y para construir el Transfer Object compuesto que representa el modelo. El cliente no necesita conocer c�mo construir el modelo o los distintos componentes que proporcionan los datos para ensamblar el modelo.
  • Reduce el Acoplamiento entre los Clientes y el Modelo de la Aplicaci�n
    El Transfer Object Assembler oculta a los clientes la complejidad de la construcci�n de los datos del modelo y establece un acoplamiento ligero entre los clientes y el modelo. Con este acoplamiento ligero, si el modelo cambia, el Transfer Object Assembler tambi�n requerir� ese cambio. Sin embargo, el cliente no depende de la constucci�n del modelo ni de las relaciones entre los componentes del modelo de negoico, por eso los cambios en el modelo no afectan directamente al cliente.
  • Mejora el Rendimiento de Red
    El Transfer Object Assembler reduce dr�sticamente la sobrecarga de red que producen las llamadas a m�todos remotos. El cliente puede solicitar datos del modelo de la aplicaci�n desde el Transfer Object Assembler con una s�la llamada a m�todo. El ensamblador construye y devuelve el Transfer Object compuesto. Sin embargo, este Transfer Object compuesto podr�a contener una gran cantidad de datos. As�, aunque el Transfer Object Assembler reduce el n�mero de llamadas a trav�s de la red, hay un incremento en la cantidad de datos transportados en cada llamada. Este inconveniente se debe tener en cuenta cuando apliquemos este patr�n.
  • Mejora el Rendimiento del Cliente
    El Transfer Object Assembler del lado del servidor construye el modelo como un Transfer Object compuesto sin utilizar ning�n recurso del cliente. El cliente no utiliza su tiempo para ensamblar el modelo.
  • Mejora el Rendimiento de la Transaci�n
    Normalmente, las actualizaciones se a�slan en una parte muy peque�a del modelo y se pueden realizar mediante transaciones espec�ficas. Estas transaciones se enfocan en las partes aisladas del modelo en lugar de bloquear el objeto gen�rico (modelo). Despu�s de que el cliente obtiene el modelo y lo muestra o procesa localmente, el usuario (o cliente) podr�a necesitar actualizar o modificar el modelo. El cliente puede interact�ar directamente con un Session Facade para conseguir esto a un nivel de especificidad aceptable. El Transfer Object Assembler no est� implicado en la transaci�n para actualizar o modificar el modelo. Hay un mejor control del rendimiento porque el trabajo de transaciones con el modelo sucede con el nivel de especificidad apropiado.
  • Podr�a Presentar Transfer Objects Obsoletos
    El Transfer Object Assembler construye Transfer Objects bajo pedido. Estos Transfer Objects son fotograf�as del estado actual del modelo, representadas por varios componentes de negocio. Una vez que el cliente obtiene un Transfer Object del ensamblador, este Transfer Object es enteramente local al cliente. Como los Transfer Objects no se preocupan de la red, otros cambios hechos a los componentes de negocio usados para construir el Transfer Object no se ver�n reflejados en �ste. Por lo tanto, despues de obtener el Transfer Object, se puede convertir en obsoleto r�pidamente si hay transaciones sobre los componentes de negocio.

.�C�digo de Ejemplo

.�Implementar el Transfer Object Assembler

Consideremos una aplicaci�n de control de proyectos donde varios componentes de la capa de negocio definen el modelo complejo. Supongamos que un cliente quiere obtener el modelo de datos compuesto de datos de varios objetos de negocio, como:

  • Informaci�n del Proyecto desde el componente Project.
  • Informaci�n del Manager del Proyecto desde el componente ProjectManager.
  • Lista de Tareas del Proyecto desde el componente Project.
  • Informaci�n de Recursos desde el componente Resource.

Se puede definir un Transfer Object compuesto como se ve en el siguiente ejemplo. Se puede implementar un Transfer Object Assembler para ensamblar este Transfer Object.

 
public class ProjectDetailsData {
  public ProjectTO projectData;
  public ProjectManagerTO projectManagerData;
  public Collection listOfTasks;
  ...
}

El listado de tareas de ProjectDetailsData es una collection de objetos TaskResourceTO. TaskResourceTO es una combinaci�n de TaskTO y ResourceTO. Abajo podemos ver estas clase:

Ejemplo de la clase TaskResourceTO:


public class TaskResourceTO {
  public String projectId;
  public String taskId;
  public String name;
  public String description;
  public Date startDate;
  public Date endDate;
  public ResourceTO assignedResource;
  ...

  public TaskResourceTO(String projectId, 
    String taskId, String name, String description, 
    Date startDate, Date endDate, ResourceTO 
    assignedResource) {
        this.projectId = projectId;
        this.taskId = taskId;
        ...
        this.assignedResource = assignedResource;
    }
    ...
}

Ejemplo de la clase TaskTO:


public class TaskTO {
  public String projectId;
  public String taskId;
  public String name;
  public String description;
  public Date startDate;
  public Date endDate;
  public assignedResourceId;

  public TaskTO(String projectId, String taskId, 
      String name, String description, Date startDate, 
      Date endDate, String assignedResourceId) {
        this.projectId = projectId;
        this.taskId = taskId;
        ...
        this.assignedResource = assignedResource;
    }
    ...
}

Ejemplo de la clase ResourceTO:


public class ResourceTO {
  public String resourceId;
  public String resourceName;
  public String resourceEmail;
  ...
  
  public ResourceTO (String resourceId, String 
    resourceName, String resourceEmail, ...) {
      this.resourceId = resourceId;
      this.resourceName = resourceName;
      this.resourceEmail = resourceEmail;
      ...
  }
}

En el siguiente listado tenemos la clase ProjectDetailsAssembler que ensambla el objeto ProjectDetailsData:


public class ProjectDetailsAssembler 
  implements javax.ejb.SessionBean {

  ...

  public ProjectDetailsData getData(String projectId){ 

    // Construct the composite Transfer Object
    ProjectDetailsData pData = new 
                      ProjectDetailsData();

    //get the project details; 
    ProjectHome projectHome = 
        ServiceLocator.getInstance().getHome(
          "Project", ProjectEntityHome.class);
    ProjectEntity project = 
      projectHome.findByPrimaryKey(projectId);
    ProjectTO projTO = project.getData();
  
    // Add Project Info to ProjectDetailsData
    pData.projectData = projTO;

    //get the project manager details;
    ProjectManagerHome projectManagerHome =
      ServiceLocator.getInstance().getHome( 
        "ProjectManager", ProjectEntityHome.class);
  
    ProjectManagerEntity projectManager = 
      projectManagerHome.findByPrimaryKey(
        projTO.managerId);

    ProjectManagerTO projMgrTO = 
      projectManager.getData();
  
    // Add ProjectManager info to ProjectDetailsData
    pData.projectManagerData = projMgrTO;

    // Get list of TaskTOs from the Project
    Collection projTaskList = project.getTasksList();

    // construct a list of TaskResourceTOs
    ArrayList listOfTasks = new ArrayList();
  
    Iterator taskIter = projTaskList.iterator();
    while (taskIter.hasNext()) {
      TaskTO task = (TaskTO) taskIter.next();

      //get the Resource details; 
      ResourceHome resourceHome = 
      ServiceLocator.getInstance().getHome( 
        "Resource",         ResourceEntityHome.class);
  
      ResourceEntity resource = 
        resourceHome.findByPrimaryKey(
          task.assignedResourceId);

      ResourceTO resTO = resource.getResourceData();

      // construct a new TaskResourceTO using Task
      // and Resource data
      TaskResourceTO trTO = new TaskResourceTO( 
              task.projectId, task.taskId,
              task.name, task.description,
              task.startDate, task.endDate,
              resTO);

      // add TaskResourceTO to the list
      listOfTasks.add(trTO);
    }
    
    // add list of tasks to ProjectDetailsData
    pData.listOfTasks = listOfTasks;

    // add any other data to the Transfer Object
    ...
  
    // return the composite Transfer Object
    return pData;

  }

  ...
}

.�Patrones Relacionados

  • Transfer Object
    Transfer Object Assembler usa el patr�n Transfer Object para poder crear y transportar Transfer Objects al cliente. Los Transfer Objects creados llevan los datos que representan el modelo de la aplicaci�n desde la capa de negocio hasta los clientes que han solicitado los datos.
  • Composite Entity
    El patr�n Composite Entity promueve el dise�o de un bean de entidad gen�rico, donde las entidades pueden producir Transfer Objects compuestos similares al producido por el Transfer Object Assembler. Sin embargo, el Transfer Object Assembler es m�s aplicable cuando el Transfer Object compuesto construido se deriva de varios componentes (beans de sesi�n, beans de entidad, DAOs, etc.), mientras que el patr�n Composite Entity construye el Transfer Object desde sus propios datos (es decir, un �nico bean de entidad).
  • Session Facade
    El Transfer Object Assembler se implementa t�picamente como un bean de sesi�n sin estado. Como tal, podr�a ser visto como una aplicaci�n especial limitada del patr�n Session Facade. M�s importante, Transfer Object Assembler construye Transfer Objects que no se pueden modificar. Por lo tanto, el cliente que lo recibe s�lo puede utilizarlo para prop�sitos de presentaci�n y procesamiento. El cliente no puede actualizar el Transfer Object. Si el cliente necesita actualizar los objetos de negocio de los que deriva el Transfer Object compuesto, podr�a tener que acceder al Session Facade (bean de sesi�n) que proporciona ese servicio de negocio.
  • Data Access Object
    Una posible estrategia para el Transfer Object Assembler implica obtener datos para el Transfer Object compuesto desde almacenamiento persistente sin utilizar beans enterprise. En estos casos se puede aplicar el patr�n Data Access, y aprovecharnos de sus beneficios parar proporcionar acceso al almacenamiento persistente al Transfer Object Assembler.
  • Service Locator
    El Transfer Object Assembler necesita localizar y utilizar varios objetos de negocio. Se puede utilizar el patr�n Service Locator en conjunci�n con el patr�n Transfer Object Assembler siempre que sea necesario localizar un objeto o servicio de negocio.

COMPARTE ESTE ARTÍCULO

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