Trabajo de Objetos II

18
Role Object Pattern El objetivo del patrón es ofrecer una solución al problema de roles gracias a la utilización de un conjunto de objetos rol que pueden ser incorporados o eliminados de manera dinámica a un objeto core. Galiano, Natalia- Torres, Tamara

Transcript of Trabajo de Objetos II

Role Object Pattern El objetivo del patrón es ofrecer una solución al problema de roles gracias a la utilización de un conjunto de objetos rol que pueden ser incorporados o eliminados de manera dinámica a un objeto core.

Galiano, Natalia- Torres, Tamara

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

2

Intención/ propósito

Adapta un objeto a las diferentes necesidades de un cliente, de manera transparente a través del enlace con objetos rol,

cada uno de los cuales representa un rol que el objeto desempeña en el contexto del cliente. El objeto maneja su

conjunto de roles dinámicamente. Para representar roles como objetos individuales, los diferentes contextos se

mantienen separados simplificando la configuración del sistema.

Motivación

Un sistema orientado a objetos se basa típicamente en un conjunto de claves de abstracción. Cada una es modelada por

su correspondiente clase en términos abstractos de estado y comportamiento. Esto funciona usualmente bien para el

diseño de pequeñas aplicaciones. Sin embargo, una vez que se quiere escalar el sistema en un conjunto integrado de

aplicaciones, debemos lidiar con diferentes clientes que necesitan vistas de contexto específico de cada una de nuestras

claves de abstracción.

Supongamos que estamos desarrollando un software para dar soporte a la administración de la compra y venta de

inmuebles de una inmobiliaria. Una de las claves de abstracción se expresará entonces con el concepto de cliente. Por lo

que en nuestro modelo de diseño incluirá una clase Cliente. La interfaz de esta clase proveerá operaciones para

manipular los atributos del Cliente tales como la dirección, nombre, apellido, teléfono, ventas/compras de inmuebles

realizadas a través de la inmobiliaria.

Asumamos que la sección de administración de alquileres de la inmobiliaria también necesita un software de soporte.

Parece entonces que nuestra clase modelada hasta ahora es inadecuada para permitirle al Cliente actuar como

Locador, por ejemplo. Obviamente, debemos proveer una mayor implementación de estado y operaciones para

administrar los alquileres de un locador, así como también los alquileres de los cuales dispone un Locatario .

Integrar muchos contextos específicos en la misma clase Cliente conducirá probablemente a que las claves de

abstracción de la interfaces queden superpuestas. Tales interfaces serán difíciles de entender y de mantener. Los

cambios inesperados deberán ser tratados con cuidado y dispararán muchas re-compilaciones. Los cambios en partes

especificas de la interfaz de la clase Cliente afectarán probablemente a los Clientes en otros subsistemas y así como

también en otras aplicaciones.

Una solución simple tal vez sea extender la clase Cliente incorporando las subclases Comprador, Vendedor, Locador y

Locatario que capturarán el contexto específico de Comprador, Vendedor, Locador y Locatario respectivamente. Desde

el punto de vista de la identidad del objeto, la sub-clasificación implica que dos objetos de diferentes subclases no son

idénticos, por más que pertenezcan a la misma super- clase. Así, un Cliente que actúa como Vendedor y como Locador

es representado por dos objetos diferentes con sus respectivas identidades. La identidad solo puede ser simulada con un

mecanismo adicional. Si dos objetos no están destinados a ser idénticos, sus atributos heredados deben ser

constantemente chequeados para mantener la consistencia. Sin embargo, caeremos inevitablemente en problemas en

el caso de búsquedas polimórficas, por ejemplo cuando queramos obtener la lista de todos los Clientes del sistema, un

mismo objeto Cliente aparecerá repetidamente a menos que nos encarguemos de eliminar los “duplicados”.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

3

Lo que nos sugiere el patrón Rol Object es modelar las vistas de contexto específico del objeto en un objeto de rol por

separado, que puede ser dinámicamente asociado o eliminado del objeto core. Llamamos a esto una estructura de

composición de objeto que consiste en el core y sus diferentes roles. El sujeto juega a menudo varios roles y el mismo

rol puede ser probablemente jugado por diferentes sujetos. Como un ejemplo consideremos dos Clientes distintos que

son, Comprador y Vendedor dentro de la inmobiliaria, respectivamente. Ambos roles pueden ser jugados por un objeto

Cliente simple.

Figura 1: Jerarquía de Clientes en un ambiente inmobiliario.

La clave de abstracción Cliente es definida como una super-clase abstracta. Esta sirve entonces como una interfaz pura

que no define ninguna implementación. La clase Cliente específica las operaciones para manejar los atributos del cliente

(domicilio, nombre, apellido, teléfono, etc.) y define un protocolo mínimo para manejar los roles. La subclase

ClienteCore implementa la interfaz de Cliente.

La super-clase común para los roles específicos es ClienteRol, que también implementa la interfaz Cliente. La clase

ClienteRol es abstracta y no está hecha para ser instanciada. Las subclases concretas de ClienteRol, por ejemplo

Comprador, Vendedor, Locador y Locatario, definen e implementan la interfaz para roles específicos. Sólo estas

subclases pueden ser instanciadas en tiempo de ejecución. La clase Vendedor define la vista de contexto específico para

objetos que necesita la sección de administración de la compra y venta de inmuebles de una inmobiliaria. Define

operaciones adicionales para administrar las condiciones de venta del inmueble, historial de ventas realizadas, etc. De

manera similar, la clase Locador adiciona operaciones específicas para la sección de administración de alquileres de la

inmobiliaria .

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

4

Figura 2: Diagrama de objetos del patrón Role Object

Un cliente como el de la aplicación de la inmobiliaria puede trabajar con objetos de la clase ClienteCore, utilizando la

interfaz de la clase Cliente, o mediante objetos de las subclases concretas de ClienteRol. Supongamos que la aplicación

conoce una instancia particular de cliente a través de su interfaz Cliente. La aplicación puede verificar si el objeto Cliente

desempeña el rol de Vendedor. Con este fin invoca al mensaje tieneRol() con una adecuada especificación del rol. A los

efectos de nuestro ejemplo, asumimos que podemos designar roles mediante un simple string. Si el objeto Cliente

puede desempeñar el rol denominado Vendedor, la aplicación le solicitará que devuelva una referencia al objeto

correspondiente. La aplicación ahora puede utilizar esta referencia para invocar las operaciones específicas de

Vendedor.

A continuación se detallará las propiedades de este patrón, debe tenerse en cuenta que cuando se mencione el

término Cliente, este no se referirá al cliente de nuestro ejemplo antes mencionado.

Aplicabilidad

Use el patrón Role Object, si:

se necesita manejar una clave de abstracción en diferentes contextos y no se quiere colocar la interfaz que resulta del contexto específico dentro de la misma interfaz de la clase.

se necesitan manejar los roles disponibles dinámicamente de manera que puedan ser asociados y eliminados bajo demanda, es decir en ejecución, en lugar de componerlos de manera estática en tiempo de compilación.

se quiere tratar las extensiones de manera transparente y se necesita preservar la identidad lógica del objeto del grupo de objetos resultante.

se necesita mantener el rol/cliente como un par independiente uno del otro de manera que los cambios en un rol no afecten a los clientes que no están interesados en dicho rol.

No utilice este patrón

si sus potenciales roles tienen fuertes interdependencias.

Hay diversas variaciones de diseño utilizando roles. Fowler presenta una guía de esas variaciones y enseña cuando

utilizar que patrón [Fowler97].

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

5

Estructura

La siguiente figura ilustra la estructura del diagrama de clases del patrón Role Object.

Figura 3: Diagrama de la estructura del patrón Role Object

Participantes

Componente () - modela una clave de abstracción particular a través de la definición de su interfaz;

- especifica el protocolo que permite agregar, remover, testear y generar consultas para los objetos rol. Los clientes proveen especificación para las subclases de RolConcreto. En el caso más simple, el rol es identificado por un string.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

6

ComponenteCore ()

- implementa la interfaz definida por Componente e incluye el protocolo de administración del rol;

- crea instancias de objetos RolConcreto;

- administra los objetos rol.

ComponenteRol ()

- mantiene una referencia a un objeto ComponenteCore;

- implementa las operaciones que define la interfaz de Componente reenviando las peticiones a través de su referencia a ComponenteCore.

RolConcreto ()

- modela e implementa el contexto específico de la interfaz Componente;

- puede ser instanciado con un ComponenteCore pasado como parámetro.

Colaboraciones

Los objetos rol y principal colaboran de la siguiente manera:

ComponenteRol reenvía las peticiones a través de su referencia a ComponenteCore; ComponenteCore instancia y administra objetos RolConcreto.

Los clientes interactúan con los objetos rol y principal de la siguiente manera:

Los clientes pueden extender objetos ComponenteCore por medio de objetos rol. Con este fin, el cliente describe los roles que desea por medio de especificaciones de objetos.

Siempre que el cliente necesite trabajar dentro de un objeto core con un rol de manera específica, debe consultar al objeto core por dicho rol. Si el objeto ComponenteCore está actualmente desempeñando el rol solicitado, éste es devuelto al cliente.

Si el objeto Core no está desempeñando el rol solicitado, se arroja un error. Un objeto ComponenteCore nunca crea objetos rol por sí solo.

Consecuencias

El patrón Role Object tiene las siguientes ventajas y consecuencias:

La clave de abstracción puede ser definida concisamente. La interfaz de Componente se focaliza en el estado y

comportamiento esencial de la clave de abstracción modelada y no es sobrecargada con los contextos

específicos de las interfaces de rol.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

7

Los roles pueden ser asociados fácilmente e independientemente unos de otros. Extender la interfaz

Componente es muy fácil debido a que no conlleva a cambios en la clase ComponenteCore. Una instancia de la

clase RolConcreto permite añadir nuevos roles e implementarlos mientras se conserva intacta la clave de

abstracción.

Los objetos rol pueden ser añadidos y eliminados dinámicamente. Un objeto rol puede ser añadido y eliminado

en tiempo de ejecución simplemente asociándolo o desasociándolo del objeto Core. Así, solo aquellos objetos

que son requeridos en una situación particular son los que se crean.

Las aplicaciones mejoran el acoplamiento. Separando explícitamente la interfaz Componente de sus roles, el

acoplamiento de las aplicaciones basadas en diferentes roles decrementa. Una aplicación (un cliente A) que

utiliza una interfaz Componente y algunas clases de RolConcreto no necesita conocer a la clase concreta de rol

que son utilizadas en otras aplicaciones (un cliente B). [interoperabilidad de aplicaciones].

Se evita la explosión combinacional de clases a través de la herencia múltiple. El patrón evita la explosión

combinacional de clases que resulta de utilizar herencia múltiple para componer los diferentes roles en una

misma clase.

El patrón objeto de rol tiene las siguientes desventajas y obligaciones:

Es probable que los clientes se vuelvan más complejos. Trabajar con un objeto a través de las interfaces de

RolConcreto implica una leve sobrecarga de codificación comparada con usar la interfaz provista por la interfaz

de Componente. Un cliente tiene que chequear si el objeto maneja el rol en cuestión. Si es así, el cliente necesita

preguntar por el rol. Si no es así, el cliente es entonces responsable de extender el objeto Core en un contexto

de uso especifico que permita al objeto Core manejar ese rol.

Mantener las limitaciones entre los roles puede resultar dificultoso. Dado que un objeto consiste en varios

objetos que son mutuamente dependientes, mantener las limitaciones y preservar la consistencia en su

totalidad, podría resultar difícil. En la sección de implementación se profundizara al respecto.

Las limitaciones en las roles no pueden ser forzadas por el tipo de sistema. Tal vez se quiera excluir que ciertos

roles combinados sean asociados al mismo Componente. O que ciertos roles dependan de la existencia de

otros. Con el patrón Role Object, no es posible que dicha responsabilidad recaiga en el tipo de sistema. Se

tendrán que utilizar en cambio, chequeos en tiempo de ejecución.

Es probable que mantener la identidad de los objetos se vuelva más complejo. El objeto Core y sus instancias de

rol forman una unidad conceptual que debería tener una identidad conceptual por sí misma. Mientras que la

identidad del objeto puede ser manipulada directamente mediante cualquier lenguaje de programación, el

chequeo de la identidad conceptual requiere de operaciones adicionales en la interfaz Componente. Esto puede

ser implementado comparando las referencias del objeto Core.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

8

Implementación

La implementación del patrón Role Object debe abordar dos cuestiones criticas: extender transparentemente la clave de

abstracción con roles, y manipular dinámicamente esos roles. Para la extensión transparente, usamos el patrón

Decorator [Gamma+95]. Para la creación y manipulación dinámica de roles, aplicamos el patrón Product Trader

[Bäumer+97].. Así el patrón Role Object combina dos patrones conocidos y de este modo le agrega una semántica

nueva:

Proporcionar una interfaz de conformidad. Dado que queremos que los objetos rol sean usados

transparentemente dondequiera que el objeto Core pueda ser utilizado, deben brindar soporte a la interfaz

común. Podemos notar que desde el punto de vista del modelado, una clase rol es considerada una

especialización del Core (por ejemplo un Vendedor es un Cliente). El patrón Decorator nos dice como hacer

esto. Primero, obtenemos una interfaz común para todos los objetos que puede tener roles agregándolos

dinámicamente. Esta interfaz es provista por la clase Componente en el diagrama de estructura y corresponde a

la clase Componente en el patrón Decorator. Para todos los roles de contexto especifico que puedan extender

la funcionalidad de Componente, podemos insertar una super-clase abstracta de ComponenteRol, que

corresponde a la clase Decorator [Gamma+95] en el patrón Decorator. ComponenteRol implementa la interfaz

de Componente re enviando las operaciones que involucran al objeto Core. Así, los roles encapsulan

dinámicamente al Core. Las clases concretas de rol deben heredar de ComponenteRol, que se corresponde con

las clases de Decorador Concreto en el patrón Decorator [Gamma+95].

Ocultar el proceso de creación de objetos rol. Las instancias de rol son usadas para decorar el Core en tiempo de

ejecución. La cuestión clave es como la instancia Concreta de rol es creada y asociada con el objeto Core.

Podemos notar que no se pretende que estas sean creadas por el cliente. Mejor dicho, el proceso de creación

del rol debe ser inicializado por el ComponenteCore, evitando así que los objetos rol existan por su cuenta (es

decir independientemente del objeto Core). Esto también previene que los clientes conozcan como se

instancian los objetos rol.

Disociación de clases rol del Core. La creación y manipulación de roles debería ser realizado de manera genérica.

De otra forma, llega a ser difícil incluso imposible extender el ComponenteCore con nuevos e imprevistos roles

sin cambiar la implementación. Por ello, tanto el proceso de creación como de administración debe ser

independiente de las clases concretas de rol; el código del ComponenteCore no debe referenciar estáticamente

a ninguna de ellas.

Esto puede ser alcanzado mediante el uso especificación de objetos. Para solicitar un rol los clientes envían una

especificación de objeto al Core. La solución más simple es usar un tipo de nombre como especificación (ver en

la sección de motivacion). El Core devuelve el objeto rol que coincide con la especificación [Riehle95, Evans+97]..

La misma especificación de objetos puede utilizarse para la creación. Para lograr eso, el patrón Product Trader

puede ser utilizado [Bäumer+97]. El objeto de rol comerciante mantiene un contenedor con especificaciones de

objetos asociadas a los objetos de creación, por ejemplo con objetos de clase, etc. Cuando un cliente quiere

agregar un nuevo rol, este le envía la especificación del rol al Core. El Core entonces delega la creación del

objeto rol al objeto Trader.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

9

Seleccionar la especificación de objetos apropiada. En muchos casos será suficiente con utilizar un tipo de

nombre como especificación de objeto. Pero a menudo vale la pena usar especificaciones más complejas:

Supongamos que se ha modelado Persona como clase objeto Core. Algunas personas tal vez sean empleados,

por lo que existe un rol tipo Empleado. Debido a que existen diferentes tipos de empleados, se pretende hacer

que Empleado sea una interfaz y modelar las clases concretas de rol como subclases de empleado, por ejemplo,

operador de ventas, desarrollador y manager. Cuando un cliente necesita información para calcular el salario de

la persona, solicitara el rol “Empleado” al Core. Esto no se puede hacer usando tipos nombre, porque los objetos

concretos de rol serán “Operador de ventas”, etc. como tipo nombre. En tales situaciones se puede utilizar el

patrón Type Object como especificación [Johnson+97]. El Core puede resolver la solicitud de objeto rol

evaluando las sub/super tipos relacionados.

Gestión de los objetos rol. Para permitir que el objeto Core gestione sus roles, la interfaz Componente establece

un protocolo de administración de rol, que incluye operaciones para agregar, eliminar, testear y consultar los

objetos rol. Para apoyar el protocolo de administración de rol, el objeto Core, mantiene un diccionario que

mapea especificaciones de rol con una instancia concreta de rol. Sea cuando fuere, que el objeto rol sea

asociado al Core, el nuevo objeto rol es registrado en el diccionarios de rol junto con su especificación.

Notamos que el objeto Core administra sus objetos rol a través de las referencias a un tipo de ComponenteRol,

de este modo se excluyen instancias de ComponenteRol actúen como roles. Porque el Core tiene sus propios

roles, se debe hacer cargo de ellos. En particular, debe eliminarlos cuando el mismo es eliminado.

Mantener el estado de los objetos Core y rol de manera consistente. Cambios en los objetos core/rol pueden

demandar actualizaciones adicionales de los objetos rol. Como ejemplo, consideremos una modificación en el

nombre de un Persona que es a su vez Locador . Cada vez que la Persona cambie su nombre, se debe levantar un

bandera en el rol de Locador para indicar que éste modificó su nombre. La bandera indica al sistema que el

cambio de nombre debe ser reportado al Veraz nacional. La notificación es obligatoria para la inmobiliaria. Hay

diversas soluciones posibles para garantizar estas restricciones, lo cual trae aparejado un precio; usualmente las

dependencias están hardcodeadas. Se discuten soluciones más elaboradas en el próximo ítem.

Mantener las restricciones de los atributos de rol utilizando Property y Observer. Si la integración del estado se

torna compleja debido a varias interdependencias, la implementación del estado de un objeto core (o partes de

la misma) podría ser representada utilizando lista de propiedades ([Riehle97], también denominada Variable

Estado [Beck96]). Una lista de propiedades es una lista de pares clave/valor, la cual representa atributos nombre

y valor, respectivamente. Es usualmente implementada como un diccionario, que mapea el atributo nombre con

el atributo valor.

Un objeto rol puede registrar interés en un atributo particular definido como una parte del estado del objeto

core y ser notificado si se produce un cambio en el estado. Para permitir esto, cada objeto rol que modifica

un atributo debe informar al objeto core de tal manera que éste pueda notificar a los objetos rol

dependientes sobre el cambio.

Las listas de propiedades suelen ser percibidas como una mala práctica, puesto que rompen la encapsulación al

exponer la implementación del estado. Los cambios en el atributo nombre pueden exigir que todas las clases rol

que dependan de él cambien consecuentemente. Por otra parte, un código erróneo podría causar efectos

secundarios no deseados. Sin embargo, cuando se manejan cuidadosamente, esos problemas pueden ser

evitados. Tal vez el ejemplo más conocido de uso prolongado de este patrón es el de la estructura en forma de

árbol, la clave de la abstracción en varios compiladores y entornos de desarrollo de software.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

10

Mantener la identidad conceptual. El patrón Role Object permite gestionar el core y sus roles como un solo

objeto conceptual con un estado integrado. Por lo tanto, debería ser posible para los clientes saber si dos

objetos técnicamente distintos son en realidad parte del mismo objeto lógico, es decir si son conceptualmente

idénticos.

Diferentes objetos rol comparten la identidad de un objeto conceptual siempre que tengan el mismo objeto

core.

Por ejemplo, consideremos una aplicación de cliente, la cual trabaja directamente con el objeto core a través de la

interfaz de Componente que se refiere a su instancia rol utilizando una interfaz de rol concreta. Desde un punto

de vista técnico, las dos referencias no apuntan al mismo objeto sino que ambas referencian a dos objetos

técnicamente distintos. Por lo tanto, para hallar las dos referencias que realmente indican el mismo objeto

conceptual, el cliente debe usar operaciones de comparación de identidad especiales provistas por la interfaz de

Componente. Usualmente, esto se llevará a cabo como una comparación directa de dos referencias a objetos

core.

Mantener las restricciones entre roles. Entre los roles mismos (no sólo su estado) puede haber una serie de

limitaciones. Un caso común es que un rol B necesite un rol A que ya había sido desempeñado por el objeto. Por

ejemplo, si Vendedor y Locador son ambos roles de Persona, entonces la existencia del rol Cliente es una

precondición para permitir que una Persona desempeñe el rol Vendedor. Se trata de restricciones a nivel rol. La

capacidad de un objeto de desempeñar un rol B en particular se limita al caso en que el objeto aún desempeñe

el rol A. Sin el rol A, el rol B no puede ser desempeñado. Estas limitaciones surgen del dominio de aplicación.

En términos generales, el rol B no puede depender de un rol A y además un rol A constituye un estado

particular. Para los casos más complejos, no existe la capacidad de evitar el uso de un sistema de

resolución de restricciones. Afortunadamente, en la práctica, la situación casi nunca escala hasta tal

complejidad, y las soluciones más pragmáticas son suficientes. Los casos típicos pueden ser resueltos mediante

el uso de un protocolo de dos fases, de manera de consultar por todos los roles primero para luego ejecutar

la petición, por ejemplo antes de eliminar un objeto rol.

Mantener las limitaciones entre roles mediante recursividad aplicando el patrón Role Object. Muchos de los

problemas de las limitaciones a nivel rol pueden ser resueltos aplicando el patrón Role Object de manera

recursiva. Si el rol A es una precondición para un número de roles B, C, D, etc. entonces el rol A se puede

entender como una clave de abstracción para esos roles. Vendedor, Locador, Comprador y Locatario pueden ser

vistos como roles de Cliente, y Cliente y Garante como roles de Persona. Dado el hecho de que una Persona es

Garante y no se requiere que sea un Cliente, no es necesario modelarlo como un rol de Cliente. La siguiente

figura muestra una aplicación recursiva del patrón Role Object.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

11

Figura 4: Patrón Role Object aplicado recursivamente

En tiempo de ejecución, esto conduce a una cadena de roles y objetos principal. La siguiente figura describe la

situación:

Figura 5: Diagrama dinámico de objetos rol enlazados con otros objetos rol

Las restricciones a nivel rol son simplemente forzadas por los objetos rol ya que Vendedor, Locador, Comprador y

Locatario no se crearían a menos que el rol Cliente ya exista. Por lo tanto, el modelado de Cliente como otra clave de

abstracción para roles adicionales sirve para garantizar una restricción importante en el desempeño del rol en la clave

de abstracción mas general de Persona.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

12

Código de ejemplo

El siguiente código JAVA muestra como implementar el ejemplo discutido en la sección de motivación. Asumimos que

existe una clase componente llamada Cliente:

import java.util.List;

public abstract class Cliente {

String nombre;

String apellido;

String domicilio;

String telefono;

public String getNombre() {

return nombre;

}

public void setNombre(String nombre) {

this.nombre = nombre;

}

public String getApellido() {

return apellido;

}

public void setApellido(String apellido) {

this.apellido = apellido;

}

public String getDomicilio() {

return domicilio;

}

public void setDomicilio(String domicilio) {

this.domicilio = domicilio;

}

public String getTelefono() {

return telefono;

}

public void setTelefono(String telefono) {

this.telefono = telefono;

}

public abstract ClienteRol devolverRol(String rol);

public abstract boolean tieneRol(String rol);

public abstract void agregarRol(ClienteRol rol);

public abstract void eliminarRol(String rol);

public abstract List<Object> devolverHistorial();

}

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

13

La implementación de la clase ClienteCore podría parecerse entonces:

import java.util.List;

import java.util.Map;

public class ClienteCore extends Cliente {

Map<String,ClienteRol> diccionarioRoles;

List <ClienteRol> roles;

public List<ClienteRol> getRoles() {

return roles;

}

public void setRoles(List<ClienteRol> roles) {

this.roles = roles;

}

public ClienteRol devolverRol(String rol){

return this.buscarRol(rol);

}

private ClienteRol buscarRol(String rol) {

//Busca el rol solicitado sino se encuentra es creado.

}

public boolean tieneRol(String rol){

return (this.buscarRol(rol)!=null);

}

public void agregarRol(ClienteRol rol){

this.getRoles().add(rol);

}

public void eliminarRol(String rol){

this.getRoles().remove(this.buscarRol(rol));

}

@Override

public List<Object> devolverHistorial() {

}

}

La especificación de un rol es implementada como un string el cual es igual al nombre de la clase de RolConcreto. El

mapeo entre la especificación de rol y el objeto en si mismo se implementa con un diccionario.

A continuación definimos una subclase de Cliente llamada ClienteRol la cual se sub-clasificará para obtener diferentes

roles concreto. ClienteRol decora al ClienteCore referenciándolo a través de su variable de instancia core. Para cada

operación en la clase Cliente, ClienteRol reenvía la petición al core. Podemos notar que la variable de instancia core se

define con el tipo de ClienteCore, esto nos asegura que los roles de Cliente no son usados como objetos rol. El mapeo

entre la especificación de rol y un objeto creador apropiado, el cual es capaz de instanciar el rol especificado es

implementado como una tabla de búsqueda.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

14

import java.util.List;

public abstract class ClienteRol extends Cliente{

ClienteCore core;

public ClienteCore getCore() {

return core;

}

public void setCore(ClienteCore core) {

this.core = core;

}

public ClienteRol devolverRol(String rol){

return this.getCore().devolverRol(rol);

}

public boolean tieneRol(String rol){

return this.getCore().tieneRol(rol);

}

public void agregarRol(ClienteRol rol){

this.getCore().agregarRol(rol);

}

public void eliminarRol(String rol){

this.getCore().eliminarRol(rol);

}

public List<Object> devolverHistorial(){

return this.getCore().devolverHistorial();

}

}

Las subclases de ClienteRol definen roles específicos, por ejemplo la clase Vendedor agrega operaciones para

administrar sus propiedades, pudiendo agregar nuevas propiedades, eliminar y tasar las mismas.

import java.util.List;

public class RolVendedor extends ClienteRol {

List<Propiedad> misPropiedades;

public List<Propiedad> getMisPropiedades() {

return misPropiedades;

}

public void setMisPropiedades(List<Propiedad> misPropiedades) {

this.misPropiedades = misPropiedades;

}

public void agregarPropiedad(Propiedad p){

this.getMisPropiedades().add(p);

}

public void eliminarPropiedad(Propiedad p){

this.getMisPropiedades().remove(p);

}

}

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

15

Usos conocidos

La serie de proyectos bancarios GEBOS orientados a objetos hace uso extensivo de este patrón [Bäumer+97a]. Provee

soporte de software para numerosos sectores de negocios bancarios incluyendo los cajeros y departamentos de

préstamo e inversión así como también servicios propios y de gestión de cuentas. El sistema GEBOS está basado en

capas comunes del dominio del negocio y modela los conceptos principales del banco. Las aplicaciones concretas en el

lugar de trabajo extienden esos conceptos mediante la utilización del patrón Role Object.

El Framework de Herramientas y Materiales descrito en [Riehle+95a, Riehle+95b] explora el modelado del rol en un

espacio de diseño donde el protocolo de copiar y pegar, la herencia múltiple, los decoradores y wrappers son

utilizados para lograr los mismos efectos que patrón Role Object. Estas variaciones han sido tratadas brevemente por

Fowler [Fowler97].

El sistema Geo actualmente bajo desarrollo por Ubilab, el laboratorio de investigación en tecnología de la información

del Union Bank de Suiza, está utilizando el patrón Role Object como una variación en la implementación de roles como

entidades de programación de primera clase.

Kristensen y Østerbye utilizan el patrón Decorator para introducir roles dentro de los lenguajes de programación

[Kristensen+96]. Sin embargo, no se ocupan de cuestiones relativas a la creación y gestión de objetos rol en detalle.

Hemos utilizado un ejemplo de un dominio específico, Persona y sus roles, para ejemplificar el objetivo. Este ejemplo es

tan común que verdaderamente representa el patrón en sí mismo. Dado que se necesita una abstracción de Persona en

numerosos contextos, hay también un variado número de diferentes roles que debe desempeñar. Schoenfeld aborda

varios ejemplos, como Persona y sus roles, en procesos de negocios centrados en documentos [Schoenfeld96]. En

nuestro caso seleccionamos Persona y sus roles dentro de un sistema inmobiliario con clientes. Otro ejemplo sería

Persona y sus roles dentro de una jerarquía burocrática y los problemas relacionados con la gestión de nóminas.

Un uso no relacionado con el patrón Role Object es la decoración de nodos en arboles de sintaxis abstracto.

Los ATS son la abstracción primaria en la mayoría de los ambientes de desarrollo de software. Son vistos y usados en

muchas herramientas diferentes, por ejemplo en editores de sintaxis directos, buscadores de símbolos, referencias

cruzadas, soporte de compilación, análisis de dependencias y herramientas de impacto de cambios. Cada herramienta

necesita anotar en los nodos AST información específica aún si actualmente está interesada sólo en pequeños aspectos

del árbol entero. Mitsui y otros plantean el uso del patrón en el contexto del ambiente de programación C++

[Mitsui+93], para el empleo específico así como también para propósitos más generales.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

16

Patrones relacionados

El patrón Extension Object aborda la misma cuestión: un componente es extendido a través de objetos de extensión de

tal manera que satisfacen los requerimientos de contexto específico. El patrón, sin embargo, no muestra como

Componente y Componente Rol son tratados transparentemente, lo cual se considera el aspecto clave en la aplicación

del patrón Rol Object. Además, el patrón Extension Object solo toca el tema de la extensión del objeto (objeto rol) en

cuanto a creación y administración. Podemos ver que la integración del patrón Decorator y el patrón Product Trader

resultan ser la clave del patrón Rol Object.

La diferencia básica con el patrón Extension Object es que la extensión se conoce y se busca para un determinado

procedimiento y además tanto el subject como la extensión no son subclases de la misma interfaz lo que permite que la

extensión cumpla la interfaz general de extensión pero no la misma que subject.

El patrón Extension Object ha utilizado a los efectos de modelado de roles por Zhao, Foster y Schoenfeld. Zhao y Foster

tratan el tema de los objetos rol como extensiones de objetos, por lo que no envuelven transparentemente al objeto

core. Su ejemplo clave es la noción de Punto (y sus roles) como base de los sistemas de software de transporte.

Schoenfeld elige el mismo ejemplo, antes pautado como una persona y sus roles, pero también utiliza el patrón

Extension Object mas que el envolvimiento transparente del core a través del Decorator.

El patrón Post describe una variable interesante del patrón. Similar al patrón Extension Object, describe las

responsabilidades del objeto core en el contexto particular de la aplicación. Sin embargo, el objeto post existe

independientemente del core y puede vivir sin ser asignado a uno.

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

17

Referencias

Bäumer+97 Dirk Bäumer and Dirk Riehle. “Product Trader.” In *Martin+97+. Chapter 3.

Bäumer+97a Dirk Bäumer, Guido Gryczan, Rolf Knoll, Carola Lilienthal, Dirk Riehle, and Heinz Züllighoven.

“Framework Development for Large Systems.” Communications of the ACM 40, 10 (October

1997).

Beck96 Kent Beck. Smalltalk Best Practice Patterns. Prentice-Hall, 1996.

Coplien+95 James O. Coplien and Douglas C. Schmidt (editors). Pattern Languages of Program Design.

Addison-Wesley, 1995.

Evans+97 Eric Evans and Martin Fowler. “Specification Patterns.” Submitted to PLoP ’97.

Fowler96 Martin Fowler. Analysis Patterns. Addison-Wesley, 1996.

Fowler97 Martin Fowler. “Role Patterns.” Submitted to PLoP ’97.

Gamma+95 Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns. Elements of

Reusable Object-Oriented Software. Addison-Wesley, 1995.

Gamma97 Erich Gamma. “Extension Object.” In *Martin+97+. Chapter 6.

Johnson+97 Ralph Johnson and Bobby Woolf. “Type Object.” In *Martin+97+. Chapter 4.

Kristensen+96 Bent Bruun Kristensen and Kasper Østerbye. “Roles: Conceptual Abstraction Theory and

Practical Language Issues.” Theory and Practice of Object System 2, 3 (1996): 143-160.

Martin+97 Robert C. Martin, Dirk Riehle, and Frank Buschmann (editors). Pattern Languages of Program

Design 3. Addison-Wesley, 1997.

Mitsui+93 Kin'ichi Mitsui, Hiroaki Nakamura, Theodore C. Law, and Shahram Javey. “Design of an

Integrated and Extensible C++ Programming Environment.” Object Technology for Advanced

Software (ISOTAS-93, LNCS-742). Edited by Shojiro Nishio and Akinori Yonezawa. New York:

Springer-Verlag, 1993. Page 95-109.

Riehle+95a Dirk Riehle. “How and Why to Encapsulate Class Trees.” In Proceedings of the 1995 Conference

on Object-Oriented Programming Systems, Languages and Applications (OOPSLA ’95). ACM

Press, 1995. Page 251-264.

Riehle+95a Dirk Riehle and Heinz Züllighoven. “A Pattern Language for Tool Construction and Integration

Based on the Tools and Materials Metaphor.” In *Coplien+95+. Chapter 2.

Riehle+95b Dirk Riehle and Martin Schnyder. Design and Implementation of a Smalltalk Framework for the Tools and

Materials Metaphor. Ubilab Technical Report 95.7.1, 1995.

Riehle97 Dirk Riehle. A Role-Based Design Pattern Catalog of Atomic and Composite Patterns Structured

by Pattern Purpose. Ubilab Technical Report 97.1.1. Zürich, Switzerland: Union Bank of

Switzerland, 1997.

Schoenfeld96 Ari Schoenfeld. “Domain Specific Patterns: Conversions, Persons and Roles, and Documents and

Roles.” In Proceedings of the 1996 Conference on Pattern Languages of Programming (PLoP

’96). Washington University Department of Computer Science, Technical Report WUCS-97-07,

1997.

Zhao+97 Liping Zhao and Ted Foster. “A Pattern Language of Transport Systems (Point and Route).” In

[Martin+97]. Chapter 23.

Copyright © 1997 Dirk Bäumer, Dirk Riehle, Wolf Siberski, and Martina Wulf. All Rights Reserved.

Words: 4895 Page 11 of 11

Role Object Pattern

Galiano, Natalia- Torres, Tamara

2010

18

Dirk Bäumer works for TakeFive Software AG, Eidmattstr. 51, CH-8032 Zurich, Switzerland. He welcomes e-mail at

[email protected].

Dirk Riehle works at Ubilab, the information technology research laboratory of UBS. He can be reached at UBS,

Bahnhofstrasse 45, CH-8021 Zurich. He welcomes e-mail at [email protected] or [email protected].

Wolf Siberski works for RWG GmbH, Germany. He can be reached at RWG GmbH, Räpplenstraße 17, 70191

Stuttgart, Germany. He welcomes e-mail at [email protected].

Martina Wulf works at Union Bank of Switzerland, Bahnhofstrasse 45, CH-8021 Zurich. She can be reached at

[email protected].

Otras:

http://ootips.org/role-object.html

Product Trader Dirk Bäumer and Dirk Riehle

Extension Object Erich Gamma IFA Consulting

Dealing with Objects Martin Fowler [email protected]