taller de patrones de diseño - Introducción

Anuncio
Patrones de diseño
Máster en Bases de Datos e Internet
TABLA DE CONTENIDOS
Presentación de los patrones de diseño
TALLER DE PATRONES
DE DISEÑO
Raquel Trillo Lado
Universidad de Zaragoza
2010
3
Contextualización
Programación Estructurada VS Programación Orientada a Objetos (POO)
¿Por qué debemos conocer los patrones de diseño?
¿Qué es un patrón?
Consecuencias del uso de patrones de diseño
Clasificación de patrones de diseño
Objetivos del taller
Requisitos
3
3
7
7
9
10
11
11
Patrones Estructurales
12
El patrón Composite o Composición
El patrón Proxy
El patrón Decorator o Decorador
El patrón Facade o Fachada
El patrón Bridge o Puente*
El patrón Adapter o Adaptador*
El patrón Flyweight o Objeto Ligero*
12
22
29
39
43
45
49
Patrones de Creación
54
El patrón Prototype o Prototipo
El patrón Singleton o Instancia única*
El patrón Factory Method o Método de fabricación*
El patrón Abstract Factory o Fábrica abstracta*
El patrón Builder o Constructor*
54
58
60
63
65
Patrones de Comportamiento
68
El patrón Chain of Responsability o Cadena de Responsabilidad
El patrón State o Estado
El patrón Strategy o Estrategia
El patrón Observer u Observador
El patrón Iterator o Iterador*
El patrón Template Method o Plantilla*
El patrón Visitor o Visitante*
El patrón Command o Comando*
El patrón Memento o Recuerdo*
El patrón Mediator o Mediador*
68
73
78
82
89
92
95
98
102
104
Bibliografía y referencias
110
-2-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Codificación o implementación, donde se traduce el diseño a un
PRESENTACIÓN DE LOS PATRONES DE DISEÑO
lenguaje de programación estructurado como por ejemplo Ada,
Pascal, Cobol, Fortan,... En general esta traducción es bastante
Contextualización
• En general se han venido estudiando de forma separada Ingeniería del
directa.
Software y Diseño de Algoritmos y Programación.
•
o En general la mayoría de errores se introducen en la fase de diseño.
En Ingeniería del Software se suelen analizar los diferentes ciclos de vida de
Además cuanto más tarde se detete un error más problemas suele
construcción del software (cascada, espiral, prototipado, etc), metodología de
suponer. Debido a esto se dedica mucho tiempo a esta fase para tratar de
construcción, explotación y calidad del software (métrica, ISO 9000-3, etc.), y
evitar errores tempranos.
modelos de objetos (OMT, UML, etc.).
•
•
Máster en Bases de Datos e Internet
o Supone que los requisitos permanecen inalterados durante todo el ciclo
En Diseño de Algoritmos y Programación se suelen aprender las estructuras de
de vida y que se conocen de antemano, de modo que cambios o nuevos
un lenguaje de programación y sus características y se implementan en ese
requisitos según Horowitz en 1993 suponen un 70% del coste total en
lenguaje problemas de diferente índole.
mantenimiento.
Los Patrones de Diseño actúan como puente entre estas dos materias
o Debido a esto se introdujo el ciclo de vida de desarrollo del software en
(Ingeniería del Software y Diseño de Algoritmos y Programación). En palabras
Espiral y el Prototipado en lugar de emplear el desarrollo en Cascada o
de Donald Knuth, “First create a solution using sound software engineering
Cascada con realimentación.
techniques, then if needed, introduce small violations of good software
Cascada y Cascada con realimentación: Fundamentalmente el
engineering pinciples for efficiency’s sake”, es decir “Primero crear una
ciclo de vida del desarrollo del software se realiza en bloques.
solución usando técnicas de ingeniería del software conocidas, luego si es
Por lo tanto, en general, es necesario haber finalizado
necesario, introducir pequeños camios de los principios de ingeniería del
completamente cada una de las fases antes de pasar a la siguiente.
software bien establecidos por razones de eficiencia”.
Espiral y Prototipado. En general el ciclo de vida del desarrollo
del software es incremental de modo que se van aumentando
Programación Estructurada VS Programación Orientada a Objetos (POO)
• Programación Estructurada:
poco a poco las funcionalidades del sistema. En este tipo de
desarrollos existe gran interacción con el usuario con el fin de
o Hace unos diez años que cayó en desuso pero todavía se sigue usando
disminuir los riesgos.
sobre todo en aplicaciones legadas (legacy).
o Separación del modelo de datos (en general especificado mediante
o Comprende fundamentalmente tres fases:
diagramas Entidad-Relación o mediante ficheros) del modelo de
Análisis o captura de requisitos, donde de estudia el problema y
procesos (en general especificado mediante diagramas de flujo).
se definen las características que debe tener la solución.
No se encapsulan las operaciones que se pueden realizar sobre los
Diseño, donde se construye el algoritmo que resuelve el
datos.
problema, ajustándose a las características que se han
Cambios en uno de ellos pueden provocar fallos en el otro porque
especificado en la fase de análisis, basándose en los bloques
estructurales secuencia, condición e iteración. Por ejemplo
mediante la técnica diagramas de flujo.
-3-
no se manejan de forma integrada.
•
Programación Orientada a Objetos (POO):
-4-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o Hoy en día es la más usada aunque en ciertas áreas como por ejemplo,
y asignar responsabilidades e interacciones entre objetos. En esta
implementación de algoritmos de cálculo numérico con gran carga de
fase se suelen usar los diagramas de clases (extienden el modelo
operaciones, todavía se siguen empleando lenguajes estructurados como
conceptual de la fase de análisis enriqueciéndolo con atributos
Fortran.
métodos y relaciones de interacción), colaboración, estado y
o Se basa en la suposición de que los objetos del dominio de negocio en el
ciclos de vida de UML. (Fase de búsqueda de solución lógica)
que se está trabajando son las entidades más estables del sistema de
Codificación o implementación, al igual que en la programación
modo que cualquier diseño basado en estos objetos será más resistente a
estructurada, en esta fase, se traduce el diseño elaborado a un
los cambios en las especificaciones que puedan darse posteriormente.
lenguaje de programación. El lenguaje seleccionado suele ser un
o Fusiona el/los modelos de datos y los modelos de proceso en clases de
lenguaje orientado a objetos como por ejemplo Java, C++, C# o
objetos. Cada clase lleva incorporados los datos que requiere mediante
cualquier otro de la familia .Net, SmallTalk, etc.; aunque podría
un conjunto de atributos que representan sus características y los
ser otro tipo de lenguaje, como por ejemplo un lenguaje
procesos necesarios para manipularlos mediante un conjunto de métodos
estructurado o un lenguaje funcional (Caml, Erlang, etc.).
que representan su comportamiento. Además como ventaja adicional
o Problemas que se deben afrontar:
reduce el vacío entre el software y los modelos de negocio, de modo que
Se debe buscar un diseño reusable y suficientemente flexible a
un modelo de objetos o diagrama de interacción puede ser fácilmente
cambios y ampliaciones (escable) a la vez que eficiente.
comprensible por un empresario.
¿Cuáles son las clases y objetos que deben intervenir y qué
o Las fases en el proceso de desarrollo del software son las mismas pero
responsabilidad se le asigna a cada uno de ellos? ¿Cuál es la
los objetivos, métodos y técnicas de cada una de ellas difieren
granularidad correcta para las clases? ¿Cuándo usar la herencia
enormemente:
de clases y cuándo usar la implementación de una interfaz?
Análisis o captura de requisitos: al igual que en el la
¿Cómo deben interactuar los objetos?, es decir, ¿cómo
programación estructurada, en esta fase, se estudia el problema y
intercambian mensajes (o peticiones, request) entre ellos para
se definen las características (requisitos) que debe tener la
realizar sus funciones (o responsabilidades)? o ¿Cuáles son las
solución. La diferencia radica en que en este caso el análisis se
relaciones entre ellos?
centra en el dominio de estudio y tiene como objetivo construir
un modelo del mundo real empleando objetos. Dicho modelo
suele expresarse mediante el modelo conceptual (diagrama de
clases que resuelve el problema pero no representa una
descripción de los componentes software) y diagramas de UML
como por ejemplo los casos de uso. (Fase de investigación)
o En la metodología orientada a objetos sigue habiendo problemas
fundamentalmente por dos razones:
En algunos modelos de diseño existe un uso inadecuado de la
encapsulación de modo que hay una visibilidad de atributos y
métodos incorrecta. Esto suele provocar mayor acoplamiento
entre clases del debido, de modo que cambios en una de ellas
Diseño, el objetivo de esta fase es crear es refinar los modelos
implica cambios en las demás, es decir mayor dificultad de
obtenidos en el análisis de modo que se enriquezcan con
mantenimiento.
suficientes detalles próximos a la implementación. Debido a esto
en esta fase es necesario comprobar que se cumplen los requisitos
-5-
-6-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
En muchos casos existe un vacío entre el análisis y el diseño y
esencia pueda ser usada para resolver problemas en contextos diferentes. De este
entre el diseño y la implementación. Esto provoca que los
modo se permite el reuso de ideas (diseños) no sólo código.
modelos proporcionados en la fase de diseño no sean buenos.
•
Fundamentalmente se dan dos problemas; o bien no se han
modelo
de
modo
que
sido aplicada con éxito en el pasado(al menos una vez), la cual se cataloga de
modo que pueda ser aplicada en el futuro para resolver nuevos problemas con la
programador debe tomar decisiones de diseño sin tener
misma esencia. O lo que es lo mismo, es una solución de diseño a un problema
suficientes conocimientos del dominio; o bien existe una
no trivial efectiva y reusable (se puede aplicar a un abanico de problemas de
sobreespecificación de modo que no se proporciona suficente
diseño en distintas circunstancia).
suficientemente
el
Definición 1: Es una solución de diseño válida en diferentes contextos y que ha
el
refinado
libertar al programador (p.e. especificándole una estructura de
datos concreta en donde implementar una lista).
¿Por qué debemos conocer los patrones de diseño?
• Los diseñadores expertos saben que no se debe empezar a resolver todos los
•
¿Cómo se cataloga (describe) un patrón de diseño?
o Nombre del patrón: Describe un problema de diseño, su solución y las
consecuencias en una o dos palabras. En general se suele especificar en
castellano y en inglés.
problemas desde el principio. Además también conocen diversas soluciones ya
o Clasificación (campo opcional): Indica de que tipo es el patrón.
probadas que le evitan “reinventar la rueda”. En general Los diseñadores senior
o Propósito: Indica en dos o tres líneas cuál es el problema que intenta
normalmente reusan soluciones que ya han trabajado anteriormente y que les
han proporcionado buenos resultados.
•
Máster en Bases de Datos e Internet
resolver el patrón y su propósito.
o Otros nombres (Also Known As) (campo opcional): Si existen otros
La idea de los patrones de diseño es especificar soluciones buenas y determinar
nombres con los que es conocido en la comunidad deberían
sus características de algún modo para que puedan ser integradas en los diseños
especificarse.
de aplicaciones incluso por diseñadores no expertos. Es decir capturar la
o Motivación: Describe un ejemplo real de problema (el escenario) que ha
experiencia para poder usarla eficientemente. Esta idea aplicada hoy al software
sido resuelto con el patrón, especificando la estructura que lo resuelve (la
surgió de la arquitectura:
solución). El escenario ayudará a entender la descripción más abstracta
o Christopher Alexander “Each pattern describes a problem which occurs
que se indicará a continuación.
over and over again in our environment, and then describes the core of
o Aplicabilidad: Especifica cuáles son las situaciones donde se puede
the solution to that problem, in such a way that you can use this solution
usar. Además da ejemplos de cómo puede solucionar problemas de
a million times over, without ever doing it the same way twice”.
diseños pobres y cómo se pueden reconocer esas situaciones.
o Christopher Alexander. A Pattern Language: Towns, Buildings,
Construction, 1977. The Timeless Way of Building, 1979.
o Estructura: Especifica mediante notaciones gráficas (diagrama de
clases, colaboración y estado fundamentalmente) cuál es la solución al
problema de forma abstracta. Esta notación es sumamente importante
¿Qué es un patrón de diseño?
• Víctor Gulías “Nuevo collar para un perro viejo: Abstracción”, es decir, dada
una solución a un problema específico se trata de determinar cuál es la esencia
de la solución eliminando la parte específica del contexto, de modo que dicha
-7-
pero no es suficiente porque sólo captura el producto final del proceso de
diseño. Para poder reusar un patrón es necesario también recordar las
decisiones, alternativas y ventajas e inconvenientes a las que nos dirigen
además de ejemplos que nos puedan ayudar.
-8-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Participantes: Lista las clases y objetos que intervienen en la estructura
Máster en Bases de Datos e Internet
o El propósito, el cual trata de reflejar lo que hace el patrón. Los patrones
del patrón y especifica cuál es la responsabilidad de cada uno de ellos.
pueden ser:
o Colaboraciones entre participantes: Indica cómo interaccionan los
De creación: El próposito del patrón es crear nuevos objetos de
diferentes participantes (clases y objetos) que intervienen en su
forma transparente al sistema.
estructura.
Estructurales: Reflejan la composición formada por diferentes
o Consecuencias: Describe las ventajas e inconvenientes de la aplicación
objetos o clases con un objetivo establecido formando una
del patrón. Además se indica cómo soporta los objetivos y qué aspectos
estructura mayor. Nos indican cómo estructurar en memoria los
del sistema pueden variar.
objetos que intervienen en el problema.
o Implementación: Técnicas y peligros que conlleva la implementación
De comportamiento: Reflejan la forma de interactuar diferentes
del patrón.
objetos o clases distribuyendo su responsabilidad para lograr un
objetivo establecido.
o Código de ejemplo: Solución limitada que puede servir de base para
implementaciones que usen el patrón.
o El ámbito de aplicación, el cual trata de reflejar a que tipo de elementos
se aplica el patrón. Si se trata de relaciones entre clases estas pueden ser
o Usos conocidos (campo opcional): Ejemplos de uso del patrón en
establecidas en tiempo de compilación, mientras que si se trata de
sistemas reales.
relaciones entre objetos que pueden cambiarse de forma dinámica estas
o Patrones relacionados (campo opcional): Listado de patrones
tienen que ser establecidas en tiempo de ejecución.
relacionados incidiendo en las diferencias de uso y en el posible uso
conjunto de estos, es decir con qué patrones debería usarse.
Consecuencias del uso de patrones de diseño
• Los patrones guardan experiencias de diseño orientado a objetos. Además
Clasificación de los
patrones de diseño
más conocidos
nombran, evalúan y explican diseños que se repiten a menudo en los sistemas
orientados a objetos.
•
Facilitan el aprendizaje de diseñadores junior, y permiten ahorro de tiempo en la
Ámbito
de
li ió
Clases
Propósito
Creación
Estructural
Factory Method
o Factoría
Adapter o
Adaptador
elaboración de diseños puesto que la toma de decisiones es automática; debido a
que ayudan a escoger alternativas de diseño.
•
Facilitan la comunicación entre diseñadores debido a que establecen un marco
de referencia de terminología y justificación, puesto que son conocidas las clases
que intervienen en ellos y las interacciones entre los objetos.
•
Mejoran la documentación y el mantenimiento de las aplicaciones.
Clasificación de patrones de diseño
• Se realiza una clasificación en base a dos criterios:
-9-
-10-
Comportamiento
Interpreter o Intérprete
Template Method o
Plantilla
Patrones de diseño
apliación
Objetos
•
Máster en Bases de Datos e Internet
Abstract
Factory o
Fábrica
Abstracta
Adapter o
Adaptador
Chain of Responsability o
Cadena de responsabilidad
PATRONES ESTRUCTURALES
Bridge o Puente
Command o Comando
Patrón Composite o Composición
Builder o
Puente
Composite o
Composición
Iterator o Iterador
Prototype o
Prototipo
Decorator o
Decorador
Singleton o
Instancia única
Facade o
Fachada
•
Memento o Recuerdo
Máster en Bases de Datos e Internet
Clasificación: Estructural, debido a que nos indica cómo se organizan los
objetos en memoria para obtener una composición recursiva o lo que es lo
Mediator o Mediador
mismo una jerarquía en forma de árbol.
•
Propósito: Construir una jerarquía compuesta por dos tipos de objetos:
Observer o Observador
primitivos (nodos hoja) y compuestos (nodos internos). Los objetos compuestos
State o Estado
permiten componer objetos primitivos y otros objetos compuestos en estructuras
Flyweight o
Objeto ligero
Strategy o Estrategia
Proxy
Visitor o Visitante
arbitrariamente complejas. A este tipo de jerarquías también se le suele llamar
composiciones recursivas y jerarquías parte-todo.
El patrón permite a los clientes de los objetos composición tratar de forma
Todos los patrones aquí enumerados han sido ampliamente probados y
uniforme a los objetos primitivos y a las composiciones, es decir trata de igual
empleados en diferentes sistemas. Además no pertenecen a ningún dominio
forma a los nodos hoja como a los árboles o nodos internos.
específico sino que resuelven problemas genéricos.
•
Patrones de diseño
Algunos de los patrones aquí descritos han sido incorporados como estructuras
de lenguajes del programación como por ejemplo el patrón observador en el
lenguaje SmallTalk o el patrón Iterador en el lenguaje Java.
•
Motivación: Diseño de un editor gráfico en dónde es posible construir objetos
complejos a partir de otros más simples. El cliente que usa esta jerarquía de
objetos complejos (en este caso el Editor) está interesado en tratar de forma
uniforme a los objetos primitivos y a los compuesto para simplificar su código.
Objetivos del taller
•
Identificar las características fundamentales de los patrones más conocidos y
determinar cuándo se deben aplicar.
•
Reproducir y modificar aplicaciones sencillas en las que se aplican patrones de
diseño codificados en lenguaje Java.
Requisitos
•
Conocimientos previos: Orientación a objetos y UML.
•
Software: Java 1.5.
o El método draw() en la clase Graphic es un método abstracto, por lo
tanto se declara su signatura pero no el código que lo implementa. De
este modo se obliga a tener una implementación de este método en cada
-11-
-12-
Patrones de diseño
Máster en Bases de Datos e Internet
una de las subclases. Este método se emplea para tener una interfaz
Patrones de diseño
Máster en Bases de Datos e Internet
•
Estructura (Generalización del problema para aplicarlo a diferentes ámbitos):
•
Participantes:
común disponible para el editor de modo que pueda dibujar cualquier
objeto.
o La clase Graphic será una clase abstracta porque tiene al menos un
método abstracto.
o Para los demás métodos de la clase Graphic (los que realizan el
tratamiento de los hijos) se proporciona una implementación por defecto:
Implementación que no hace nada (se ignora)
Proporciona una excepción notificando que la operación no es
válida si se hace por un nodo hoja (puesto que estos la heredan y
no la redefinen)
Los componentes compuestos redefinen estas operaciones.
Estos métodos no pueden ser abstractos porque de ese modo los nodos
hoja no tendrían implementación de ellos (en cualquier caso no la tienen
que tener). Por otro lado es necesario poner estos métodos en la
superclase porque sino el Cliente tendría que conocer que existen dos
tipos de componentes (primitivos y compuestos).
o La flecha etiquetada con “graphics” representa la navegabilidad, es decir
el acceso va a ser siempre del objeto compuesto hacia los hijos de éste.
Depende del programador como se realice la implementación de esta
navegabilidad.
o Debido a que el rombo está pintado de negro (agregación en UML) es
responsabilidad de la clase Picture borrar todas las instancias hijas si esta
se elimina. Si se duda si el rombo debe estar rellenado o no mejor dejarlo
sin pintar.
o Las notas son sugerencias de cómo codificar los métodos cuando se
realice la programción del diseño.
•
o Component o Componente (Graphic en el ejemplo motivador):
Representa el interfaz que se les presenta a los clientes y en
general se va a tratar de una clase abstracta.
Declara la interfaz común para los objetos de la composición (los
objetos hojas y los compuestos).
Declara la interfaz para regular la composición, es decir acceder y
manipular los componentes hijos. Se suelen dar al menos las tres
operaciones de este tipo que se mencionan en la estructura (añadir
componente, borrar componente y obtener hijo).
Implementa el comportamiento por defecto para los diferentes
componentes.
o Leaf o Hoja (Rectangle, Line, Text en el ejemplo motivador):
Aplicabilidad:
o Representar composición recursiva jerárquica, es decir jerarquías todoparte.
o Ignorar las diferencias en el tratamiento de objetos primitivos
(individuales) y objetos compuestos (composiciones)
-13-
Representa un objeto primitivo, es decir un objeto hoja (sin
hijos).
Define el comportamiento de los objetos primitivos (básicos) de
la composición.
-14-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Composite o Composición (Picture en el ejemplo motivador):
o Ventaja 2: Facilita la introducción de nuevos componentes sin afectar al
cliente.
Representa un objeto compuesto, es decir el nodo raíz del árbol o
un nodo interno.
o Desventaja: Resulta complejo restringir los componenetees de un objeto
Define el comportamiento de los objetos compuestos, es decir de
compuesto, y para ello normalmente es necesario añadir comprobaciones
los componentes con hijos. Este tipo de operaciones (operation())
en tiempo de ejecución.
en este tipo de clases en general se definen mediante delegación
Por ejemplo: Imaginar que la figura compuesta tiene que estar
en los componentes hijos. Es decir, en general las operaciones de
compuesta por un conjunto de figuras elementales todas del
las hojas se definen aquí por delegación en los hijos.
mismo tipo. En este caso no es viable una comprobación en
Almacena los componentes hijos.
tiempo de compilación y habría que llevarla a cabo en tiempo
de ejecución.
Implementa las operaciones relacionadas con los hijos de la
interfaz componente. Estas operaciones son las que van a regular
la asociación.
Implementación: (Variantes del patrón y problemas que pudede desarrollar)
hijos nos interesa llegar al padre?: Definir una interfaz para acceder al
Maneja los objetos de la composición a través de la interfaz
padre de un componente en la estructura recursiva e implementarlo de la
común Componente, es decir sólo tiene conocimientos de la
forma apropiada. Varias posibilidades:
superclase de la jerarquía de clases..
Colaboraciones entre participantes:
o El cliente emplea la interfaz Componente (el API que actúa como
superclase) para interactuar con los objetos de la composición:
Si se actúa sobre una hoja, entonces la petición es realizada
directamente por la instancia correspondiente.
Si se actúa sobre una composición, en general s eredirige la
petición del compoenente a sus hijos y se realiza alguna acción
adicional (posiblemente antes o después de rediriguirle la
petición).
•
•
o Referencias explícitas al padre, es decir ¿qué pasa si a partir de los
o Client o Cliente:
•
Máster en Bases de Datos e Internet
Obtener la navegación bidireccional en la relación children o
hijos. Por ejemplo si a partir de un fichero queremos saber cuál es
su directorio padre.si es que tiene alguno. Una opción sería poner
un atributo padre en la clase Fichero (Componente) y además
añadir ahí un método obtenerPadre() que nos devuelve un
Directorio. El padre necesitaría actualizarse en tiempo de
ejecución
al
hacerse
llamadas
al
método
addChild
y
removeChild.
Esto tiene un efecto desagradable en el API y es que le damos al
cliente una referencia a la clase directorio y en principio el cliente
no debería saber que existen dos tipos de ficheros diferentes.
Consecuencias (ventajas e inconvenientes):
Establecer una relación recursiva de Fichero consigo mismo de
o Ventaja 1: Simplifica el cliente debido a que trata a los objetos
cardinalidad (0..1) de modo que se evite que el cliente tenga que
compuestos y primitivos de forma uniforme. El cliente no conoce, ni
conocer la estructura de directorios. El problema aquí es que no
debería saber con lo que está tratando. Esto simplifica el código del
se está representando lo mismo y así un componente compuesto
cliente porque evita tener que escribir funciones con sentencias
podría ser hijo de un componente primitivo. Debido a esto
condicionales (if, case, selects, etc.) para las clases de la composición.
tenemos que reforzar el modelo para evitarlo. El refuerzo del
-15-
-16-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
modelo se consigue mediante restricciones que tendrán que ser
composición es que el cliente no sea consciente de qué objetos hojas y
comprobadas en tiempo de ejecución:
compuestos se están usando. Para lograrlo la clase componente tiene que
o En general el padre debe ser un objeto compuesto
definir tantas operaciones comunes para la composición y las hojas como
(Directorio), para evitar que un nodo hoja (fichero
sea posible. En general la interfaz proporciona implementaciones por
normal) sea el padre de otro nodo (fichero normal
defecto que se reescribirán en la subclase.
o directorio).
Este objetivo a veces entra en conflicto con el principio de diseño de la
o El padre de un objeto debe tener como uno de sus
jerarquía de clases que indica que una clase sólo debería definir
hijos al objeto. La forma más sencilla de conseguir
operaciones que son significativas a sus subclases, y en este caso hay
esta restricción es cambiar sólo el padre de un
operaciones necesarias para los componentes que no tienen sentido para
objeto cuando este siendo añadido o borrado a una
las subclases. Además crea un conflicto de seguridad porque los clientes
composición.
pueden tratar de hacer operaciones poco significativas para las hojas.
o Compartición de componentes: Cuándo se trabaja con objetos muy
pesado que no poseen estado puede interesarnos compartirlos de modo
¿Cómo puede la clase componente proporcionar una implementación por
defecto para ellas?
que la representación incial en árbol deja de serlo porque se produce una
Es necesario ser creativos, por ejemplo, la interfaz para acceder a los
compartición de nodos. La representación de árbol pasa a ser la de un
hijos es fundamental para los objetos compuestos pero no es necesaria
grafo dirigido acíclico.
para los objetos hoja. Sin embargo si vemos la hoja como un
Por ejemplo si trabajamos con ficheros muy grandes y queremos
componenete que tienes hijos podemos definir una operación por defecto
tenerlos accesibles desde diferentes puntos podremos crear
para el acceso a los hijos en la superclase donde no se devuelve ningún
accesos directos a estos evitando duplicarlos.
hijo. Las hojas usarán la implementación por defecto y la clase
compuesta la refinará.
o Declaración de métodos para la manipulación de los hijos: Se
proporciona una implementación por defecto:
Implementación que no hace nada (se ignora)
Proporciona una excepción notificando que la operación no es
En este caso hay que tener cuidado con la implementación de las
válida si se hace por un nodo hoja (puesto que estos la heredan y
operaciones pues por ejemplo la operación de obtener tamaño tal
no la redefinen)
y como la habíamos planteado inicialmente aquí nos daría como
Los componentes compuestos en general redefinen estas
resultado para el directorio Raiz 1300 bytes y esto no es correcto.
operaciones y los simples las heredan.
Este tipo de implementaciones todavía se complicaría más si
quisiésemos tener la navegación en los dos niveles, es decir
o Lista de Componentes en Component? En algunas ocasiones se
ingnora la clase Composite y se sustituye el modelado por:
guardar referencias a las listas de los padres.
o Maximizar
la
interfaz
Component
Seguridad-Transparencia):
-17-
Uno
de
(Decisión
los
que
objetivos
balancea
del
patrón
-18-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
haberse modificado desde la última vez que se realizó la operación
obtener tamaño.
El uso de las cachés lleva asociado el problema de su actualización.
Cambios en los componentes hijos requeiren la invalidación de las
cachés de sus padres. De modo que este tipo de implementaciones
funcionará mejor cuando existen referencias a los padres.
o Responsabilidad de borrado. En general cuando no existe recolector de
basura lo más sencillo es hacer responsable del borrado de los hijos al
Esto incurre en una penalización de espacio para todas las hojas, porque
objeto compuesto que los contiene de modo que si se borra el objeto
tienen reservado el espacio para tener hijos aunque estas nunca lo usen.
compuesto este debe eliminar los hijos. Una excepción a esta regla se
Esta implementación es más sencilla (hay una clase menos) pero sólo
produce cuando los objetos hijos pueden ser compartidos por varios
vale la pena si hay relativamente pocos nodo hoja en la estructura.
objetos compuestos. En Java, como tiene recolector de basura, si se
Si se usa esta implementación del patrón la asociación padre encaja con
elimina un fichero de un objeto directorio simplemente bastará con
mayor facilidad haciendo la asociación children bidireccional. Sin
romper la asociación y el recolector de basura liberará la memoria
embargo se corre el peligro de que se use el espacio de los hijos en los
posteriormente del objeto eliminado de la asociación si este no está
nodo hoja para haer cualquier cosa.
referenciado por otro objeto compuesto sin tener que programar
mecanismos adicionales.
o Ordenación de hijos: Puede diseñarse un orden de los hijos de un objeto
compuestos. Por ejemplo en el editor esto puede ser interesante para
o Estructura de datos para almacenar hijos: En la fase de diseño no se
reflejar la superposición de las figuras y en el ejemplo de los ficheros
debe obligar a una estructura de datos concreta (listas enlazadas, arrays,
para reflejar la antigüedad de los ficheros creados. Otro ejemplo en el
árboles, tablas hash, etc. ) esa elección deberá tomarse en la
que podría resultar de utilidad es cuando la composición refleje árboles
implementación y dependerá de la eficiencia.
sintácticos.
•
Código de ejemplo y ejercicios:
La ordenación en los hijos se logra mediante una restricción (ORDER)
o Ejercicio 1: Obtener una representación de los árboles de directorios y
en la asociación children o hijos. Esta restricción deberá tenerse en
los ficheros que estos contienen permitiéndonos conocer el tamaño que
cuenta a la hora de realizar la implementación.
ocupan en disco. Recordad que en muchos lenguajes los directorios se
o Mejora de rendimiento usando cachés en objeto Composición. En las
implementaciones del patrón es común usar una caché a nivel del objeto
compuesto que guarde información acerca de los hijos. Por ejemplo
tratan como ficheros. (Pista: Fichero, FicheroNormal y Directorio).
o Ejercicio 2: Implementar la clase Cliente. El cliente debe crear la
siguiente estructura de directorios:
cuando estamos tratando de obtener el tamaño de un directorio que
contiene otros directorios, si realizamos la operación tal y como la hemos
implementado se llama siempre a las operaciones de todos los
descendientes a pesar de que alguna parte de la estructura puede no
-19-
-20-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
La tentación directa una vez hemos definido esto es implementar cada
una de las clases que aparece en el diagrama de forma independiente. Si
pensamos en mayor profundidad vemos que existe código muy parecido
entre por ejemplo los frames y las columnas y también entre los
caracteres y las imágenes.
Pensar como se podría realizar en diseño considerando el patrón
composición puesto que hay elementos que no pueden contener a otros
A continuación se debe mostrar por pantalla el tamaño total del fichero raíz,
elimiar el directorio usr y elininar el fichero b. Finalmente se debe obtener de
nuevo por pantalla el tamaño del fichero (directorio) raíz.
elementos del documento mientras otros si pueden..
•
Patrones relacionados: Decorador, Iterador (realizar la navegación entre los
hijos), Objeto ligero (para compartir componentes), cadena de responsabilidad,
o Ejercicio 3: Probar la clases anteriores y realizar un diagrama de
Visitante (localiza operaciones y comportamientos que deberían ser distribuidos
secuencia indicando como fluyen los mensajes entre los objetos. y hacer
a lo largo de la composición y en las clases hojas).
un diagrama de secuencia indicando como fluyen los mensajes entre lso
diferentes objetos.
Patrón Proxy
o Ejercicio 4: Aumentar el diseño anterior permitiendo la asociación padre.
•
o Ejercicio 5: Pensar en la estructura de un documento en un editor de
textos. Podría ser algo como lo que se indica a continuación:
o
Documento
Clasificación: Estructural, debido a que nos indica cómo se organizan los
objetos en memoria.
•
Otros nombres: subrogado o subrogate.
•
Propósito: Proporcionar un subrrogado o intermediario de un objeto para
controlar su acceso. El intermediario (o subrogado) controla el acceso al objeto
que estamos considerando.
*
•
*
Página
Motivación:
o Problema: En el contexto de un editor gráfico consideremos los objetos
*
Columna
*
*
*
gráficos (imágenes) que puede haber dentro de un documento.
Frame
En general no todas las imágenes van a tener que cargarse cuando
*
Imagen
se abra el documento porque depende que zona estemos
visualizando hará que se muestren o no.
La apertura del documento debería ser rápida y en general las
*
imágenes suelen ser bastante pesadas, sobre todo si son de gran
Línea Texto
tamaño.
o Solución: Debido a que no es necesario crear todos los objetos con
*
imágenes nada más abrir el documento porque no todas son visibles se
Caracter
puede hacer carga bajo demanda.
-21-
-22-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
La implementación de la carga bajo demanda por parte del editor
hace que este se complique, además la funcionalidad de carga
bajo demanda puede ser requerida por diversos módulos.
Modificar la clase imagen para que esta sepa cuando tiene que
cargarse en función de un estado interno tampoco parece una
buena opción porque esta clase se puede usar en otras
aplicaciones donde no se requiere la carga bajo demanda.
Crear una copia de la clase imagen y modificarla para permitir la
carga bajo demanda tampoco se considera un buen diseño porque
implica tener código duplicado con todas las desventajas que esto
conlleva.
Para evitar complicar el editor y dar al objeto imagen
responsabilidades que no le incumben (añadir funcionalidad
La clase ImageProxy cuando puede resolver las operaciones por
adicional a la clase imagen), se puede emplear un objeto proxy.
si misma las resuelve y proporciona el resultado (por ejemplo
Este objeto se comportará como la imagen de cara al editor pero
devolver la extención o tamaño del fichero de la imagen), en caso
será responsable de la carga bajo demanda de la imagen. En el
de que se le requiera una operación que implique la carga de la
proxy se pude almacenar el nombre del fichero como una
imagen entonces la cargará en ese momento y delegará la
referencia al objeto real (suponiendo que la imagen está en
operación correpondiente en el objeto imagen.
disco).
•
Aplicabilidad:
o Cuando exista una forma de referencia a un objeto más sofisticada que
un simple puntero, como por ejemplo las siguientes:
Proxy remoto: El proxy representa en local a un objeto remoto.
Este tipo de proxies es útil en aplicaciones distribuidas.
Proxy virtual: El proxy crea objetos costosos bajo demanda.
Proxy de protección: El proxy controla el acceso a un
El editor interactuará con el proxy, el cual delega en la imagen si
determinado recurso (objeto original). Por ejemplo si disponemos
no puede resolver la operación por si mismo y se encarga de
de una clase en concreto, denominémosla X, puede que esta no
realizar la carga bajo demanda.
realice la comprobación de los parámetros que llaman a sus
Para que el editor no tenga conocimiento de la existencia de
métodos. En muchas aplicaciones esta comprobación no será
proxies se crea una clase abstracta que propociona los métodos de
necesaria pero en algunas otras puede ser requerido.
la imagen al editor, actuando como interfaz. Esta clase abstracta
actuará como superclase del objeto proxy y del real.
-23-
-24-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
No se deberían incorporar las comprobaciones a la clase
Proporcioan la misma interfaz que el sujeto (Subject) para que un
porque esto la haría más pesada y en muchos casos no se
proxy pueda ser substituido por el sujeto real.
necesitarían (depende del cliente).
Controla el acceso al objeto real y puede ser el responsable de su
En lugar de la opción anterior el proxy puede realizar la
creación y borrado, por ejemplo el proxy podría decidir liberar de
comprobación de los parámetros. Si los parámetros son
memoria un determinado objeto (en el ejemplo motivador la
correctos el proxy delega la llamada en el objeto y sino
Imagen) porque no se está usando en ese momento. Ojo con esto
trata el problema.
porque puede ser que luego vuelvas a necesitar el objeto y la
Contar las veces que se accede a determinados métodos
creación del objeto también consume tiempo.
para determinar cuales son las operaciones más
Además en función del tipo del proxy del que se trate:
demandadas o tener uncontador de referencias al objeto
Es el responsable de codificar una petición y sus
real para controlar la concurrencia al acceder a él.
argumentos y enviarla al objeto remoto (Proxy Remoto)
disponible en una determinada dirección.
Estructura:
Actuá como caché de información del objeto real para
evitar en la medida de lo posible el acceso a este. (Proxy
Virtual o Caché).
Comprueba la corrección de los permisos y/o parámetros
de peticiones. (Proxy de protección).
o Subject (Graphic): Define la interfaz común del Proxy y el RealSubject
de modo que el proxy se pueda usar en cualquier lugar donde se espera
un sujeto real.
o RealSubject (Image): Define el objeto real que está siendo representado
por el proxy.
•
Colaboraciones entre participantes: Dependiendo de la clase de proxy, el
objeto proxy realizará una serie de operaciones y redirigirá peticiones al objeto
real que está representando. Desde el punto de vista del cliente el proxy y el
sujeto real forman un objeto compuesto en donde el proxy envuelve al objeto
real.
•
Participantes:
•
o Proxy (ImageProxy):
Consecuencias:
o Introduce un nivel de indirección en las peticiones que requieren acceder
Mantiene una referencia al objeto real (RealSubject). El proxy
al objeto, lo que conlleva a una pequeña penalización que en general
puede referirse a Sujeto o Subject si las interfaces del Sujeto y
puede permitirse.
SujetoReal o RealSubject son las mismas.
-25-
o Además dependiendo del tipo de Proxy:
-26-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
Los proxies remotos ocultan el lugar donde residen los objetos
reales.
Los proxies virtuales realizan optimizaciones como por ejemplo
la carga bajo demanda o cacheado de resultados para evitar diferir
la operación al sujeto real.
Los proxies de protección permiten realizar diversas tareas ante el
o Cuando se modifique alguna de las copias el proxy
acceso a un objeto como por ejemplo comprobar los parámetros o
solicitará la creación de la copia al objeto real.
permisos.
o Se pueden usar también en copias bajo demanda (copy-on-write o
creación bajo demanda), retrasando la replicación de un objeto hasta
que este cambia:
Crear una copia de un objeto complejo y de gran tamaño puede
ser una operación cara.
o
Además si la copia nunca se modifica no hay necesidad de
Problemas de esto: Es necesario que el proxy sepa
realizar ese gasto, usando un proxy se puede posponer el proceso
que métodos modifican el estado del sujeto real y
de copia hasta que sea requerido un cambio en la copia.
también es necesario introducir un contador en el
sujeto real.
Para copiar bajo demanda es necesario que el objeto real
tenga un contador. La copia del objeto (solicitada a través
•
Implementación:
del proxy) no hará nada más que incrementar ese contador
o Los proxies no siempre necesitan conocer el tipo del sujeto real con el
de referencias. Solamente cuando se requiera un cambio
que están trabajando. Si una clase proxy puede tratar con el sujeto real
el proxy hace una copia y el contador se decrementa.
sólo conociendo una interfaz abstracta entonces no hay necesidad de que
Además cuando la referencia es cero el sujeto real se
lo conozca y para instanciar el objeto real pueden emplear una factoría si
borra.
esta está disponible.
o Inicialmente la situación es esta:
o Es necesario que los proxies tengan algún mecanismo para referenciar
cuál es el objeto real que les corresponde antes de instanciarlo.
•
Patrones relacionados:
o Adaptador o Adapter: Un adaptador proporciona diferente interfaz al del
sujeto real (el objeto que adapta). En contraste un rpoxy proporciona la
o Cuando se solicita una copia la acción será crear
un nuevo proxy sobre el mismo sujeto real:
misma interfaz que el sujeto real. Sin embargo un proxy usado para la
protección de acceso pudiera no logra una operación que el sujeto si
logra por lo tanto su funcionalidad puede ser efectivamente un
subconjunto de la funcionalidad del objeto real.
-27-
-28-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o Decorador o decorator: Aunque pueden tener implementaciones
ventanas de la misma forma, posean las funcionalidades
similares a los proxies tiene diferente propósito. Un decorador añade más
adicionales o no por lo que no es viable modificar la clase
responsabilidades al objeto en tiempo de ejecución mientras que un
Ventana. La modificación de la clase Ventana supondría cargas
proxy controla el acceso a él. En cualquier caso variantes del patrón
adecionales para otras aplicaciones que no requieren esas
proxy son implementadas como decoradores como por ejemplo un proxy
funcionalidades.
de protección con varios niveles de control. Por otro lado los proxies
o Solución 1: La alternativa más directa para modelar este problema es
remotos y virtuales mantienen una referencia indirecta al sujeto real
usar la herencia para extender las responsabilidades de la clase Ventana y
(como por ejemplo la dirección del servicio o el nombre de la imagen) y
crear una subclase VentanaConScroll, otra VentanaActiva y otra
los decoradores mantienen una referencia directa.
ventanaActivaConScroll.
Esta solución es bastante ineficiente porque se produce una
Código de ejemplo:
o Ejercicio1:
Probar
el
código
proporcionado
que
simula
el
explosión de clases a medida que se quieran proporcionar nuevas
comportamiento del patrón y elaborar un diagrama de clases con su
funcionalidades.
estructura. ¿De qué tipo de proxy se trata y por qué?
Esta solución también es inflexible puesto que es estática y un
o Ejercico 2: Realizar un diagrama de secuencia del código proporcionado.
objeto es difícil que puede transformarse de una clase a otra
dinámicamente (en tiempo de ejecución); es decir, es una
sólución estática hecha en tiempo de compilación.
Patrón Decorator o Decorador
•
Clasificación: Estructural, debido a que nos indica cómo se establecen las
Esta solución provoca herencia múltiple que en determinados
relaciones entre los diferentes elementos en memoria.
lenguajes de programación puede ser difícil de implementar.
•
Otros nombres: wrapper.
•
Propósito: Añadir responsabilidades o características a un objeto en concreto
dinámicamente, proporcionando una alternativa flexible a la extensión de una
clase para aumentar la funcionalidad.
•
Motivación:
o Problema: En el contexto de un editor de texto consideremos las
ventanas gráficas que muestran el documento.
Se desea que las ventanas donde se muestra el documento puedan
proporcionar un borde que estará activo cuando se esté trabajando
sobre esa ventana y una barra de desplazamiento o scroll si el
o Solución 2: Debido a los problemas que supone la creación de nuevas
documento es de un tamaño considerable. Se desea añadir esa
subclases se opta por encapsular el objeto base (ventana o TextView)
responsabilidad a objetos en concreto no a una clase.
dentro de otro objeto que añade las nuevas funcionalidades (objeto
Además se pretende que estos dos funcionalidades adicionales no
decorador). Además como no se desea que el cliente diferencie entre
supongan modificar el cliente, es decir que los clientes traten las
-29-
-30-
Patrones de diseño
Máster en Bases de Datos e Internet
objetos sin decorar y decorados se
Patrones de diseño
considera una interfaz común
Máster en Bases de Datos e Internet
añadir nuevas funcionalidades que no están disponibles en el
(visualComponent).
objeto sin decorar (scroolTo, drawBorder).
El decorador redirige las peticiones al objeto base y añade las
Los clientes de los componentes visuales no hacen distinción
nuevas funcionalidades antes o después de la redirección.
entre los componentes decorados y sin decorar.
Pueden existir diferentes tipos de funcionalidades que se desean
•
Aplicabilidad:
añadir (en el ejemplo motivador en concreto son dos: Scroll y
o Añadir ó eliminar responsabilidades de objetos de forma dinámica y
borde activo) por ello se considera una interfaz (Decorador) que
transparente, sobre todo cuando no es práctico el uso de la herencia
las engloba a todas y que actúa como mecanismo encapsulador.
debido a su inflexibilidad y explosión de clases.
Esta
interfaz
puede
especializarse
proporcionando
el
comportamiento de las diferentes funcionalidades.
•
Estructura:
•
Participantes:
o Componente o Component: Define la interfaz para que el cliente trate de
forma uniforme objetos decorados que objetos básicos.
o ComponeneteConreto o ConcreteComponent: Define un objeto al cual se
le pueden agregar responsabilidades adicionales.
La superclase Decorator impelementa la interfaz del componente
o Decorador o Decorator: Mantiene una referencia al componente
visual, redirigiendo los métodos al componente que encapsula.
encapsulado (asociado) e implementa la interfaz de la superclase
Además la transparencia de la interfaz VisualComponent permite
Componente. El Decorador delega en el componente asociado las
el anidamiento de decoradores permitiendo un número no
operaciones de la interfaz.
limitado de nuevas funcionalidades.
o DecoradorConcreto o ConcreteDecorator:
(responsabilidades) al componente (refinamiento).
Las subclases decoradoras refinan los métodos del componente
añadiendo responsabilidades. Además las subclases pueden
-31-
Añade funcionalidades
•
Colaboraciones entre participantes:
-32-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o El decorador redirige las peticiones al componente asociado y
o Puede provocar la existencia de un gran número de objetos pequeños y
opcionalmente puede realizar tareas adicionales antes o/y después de
además se producen pequeñas penalizaciones por cada nivel de
redirigir la petición.
indirección introducido.
•
Consecuencias:
o Es una estructura más flexible que la herencia (la cual es estática) puesto
Implementación:
o El decorador debe cumplir la interfaz de la clase Componente para que el
que es configurable en tiempo de ejecución y evita la herencia múltiple.
cliente no distinga entre objetos básicos y decorados.
Además con el decorador las responsabiliddades pueden ser añadidas o
o Cuando sólo exista la posibilidad de añadir un tipo de funcionalidad a los
eliminadas y se evita la herencia múltiple.
objetos básicos se puede omitir la clase abstracta Decorador. En
o Evita la aparición de clases con muchas responsabilidades en las clases
general esto no es así y además conviene ponerla porque proporciona
superiores de la jerarquía permitiendo incorporar las responsabilidades
mayor flexibilidad al diseño.
incrementalmente. Esto tiene la ventaja añadida de que no es necesario
o Se debe mantener la clase Componente o Component ligera. Así la
pagar un coste por funcionalidades no requeridas. Además también es
definición de los datos de representación debería hacerse en las subclases
sencillo definir nuevos tipos de decoradores independientemente de las
porque sino se hará a las clases decoradoras muy pesadas para poder ser
clases de objetos que extienden por ejemplo para extensiones no
usadas de forma anidada. Además añadir demasiada funcionalidad en la
previstas inicialmente.
interfaz Componente aumenta la probabilidad de que se pongan
o Puede provocar problemas con la identidad de los objetos. Un decorador
características que para un caso en concreto no se utilicen.
actúa como un envoltorio transparente de un objeto componente pero
o Patrón Decorador vs patrón Estrategia: En este caso se le están
desde el pundo de vista de la identidad de los objetos un componente
añadiendo nuevas pieles (Decorador) que aumentan la funcionalida al
decorado no es idéntico al componente en si mismo puesto que no tienen
objeto base. Si en lugar de añadir funcionalidades se quisiese cambiar el
la misma referencia. Por lo tanto no se debería confiar en la identidad de
medio de conseguir la funcionalidad del objeto base entonces se
los objetos cuando usas decoradores.
emplearía el patrón Estrategia. Además el patrón estrategia se debe
¿Cuándo dos objetos son el mismo, cuando tienen la misma
aplicar también cuando la clase Component es demasiado pesada.
referencia o cuamdno forman parte del mismo objeto compuesto,
En el patrón decorador el componente no tiene que saber nada de
el cual se construye sobre el mismo objeto base?
los decoradores, es decir los decoradores son transparentes al
Se puede plantear una solución y usar un identificador calve
componente debido a que sólo se cambia un componente desde el
único (atributo id) para identificar los objetos de modo que no se
exterior.
emplee la referencia. Nótese que el identificador sólo lo tendría el
En el patrón estrategia el componente en si mismo conoce sus
objeto básico (TextView) y que los decoradores lo “heredarían”.
posibles extensiones. Además tiene referencias y mantiene las
Es decir se pondría un atributo _clave en el TextView o en
correspondientes estrategias.
Unidad y un método abstracto obtenerId(). El componente básico
•
Patrones relacionados:
devuelve el nomber en obtenerId() y los decoradores delegan en
el componente esa operación.
-33-
-34-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o Adaptador: Un decorador es diferente de un adpatador en el sentido en
Public static void main (String argv[]){
que el decorador sólo cambia las responsabilidades del objeto, no su
Cliente c = new Cliente();
interfaz. Un adaptador proporciona una interfaz completamente nueva.
Unidad ryan = new Soldado (“Ryan”);
o Composición: Un decorador puede verse como una composición
Unidad rambo = new Pistola( new Escudo(
degenerada con solo un componente (un hijo). Sin embargo un decorador
new Soldado( “Rambo”)));
añade responsabilidades no es una agregación de objetos como lo es la
System.out.prinln(“Si ” +
composición.
Rambo.obtenerNombre() + “ataca a ” +
o Estrategia: El decorador cambia la piel del objeto y la estrategia su modo
Ryan.obtenerNombre() + “, el vencedor es”
de realizar las operaciones. Son dos alternativas diferentes de cambiar un
+ c.combate(rambo, ryan).obtenerNombre());
objeto.
•
}
Código de ejemplo:
o Ejercicio 1: Crear un modelo e implementarlo para el siguiente
}
escenario. Se consideran Unidades (soldados) de un juego de estrategia.
o Ejercicio 4: Si se desease disponer del método suprimirComplemento
Estas unidades pueden defender, atacar o moverse. Además tendrán un
¿dónde sería más adecuado hacerlo disponible?. Analizar las siguientes
método descripción que nos propocionará un String con la información
opciones.
de las unidades (nombre y tipos de métodos que emplea). Las unidades
en un principio son SoldadosRaso (es decir capacidad de ataque, defensa
y movimiento 1) pero a medida que ganan experiencia pueden obtener
Opción 1: Nueva responsabilidad en la clase Complemento:
abstract class Complemento extends Unidad {
...
complementos (escudos y pistolas) que le ayuden a desarrollar su misión.
public Unidad suprime_complemento(Complemento
Por cada escudo que se adquiera la capacidad de defensa se multiplica
complemento) {
por dos y por cada pistola la capacidad de ataque se multiplica por 2
if (complemento == this)
(Pista: Fichero, FicheroNormal y Directorio).
return _sujeto;
o Ejercicio 2: Implementa una clase Cliente de la estructura anterior que
else {
poseea el siguiente método:
if (_sujeto instanceof Complemento)
+ Unidad combate(Unidad atacante, Unidad defensor)
_sujeto = ((Complemento) _sujeto)
De modo que si la capacidad de ataque de la unidad atacante es
.suprime_complemento(complemento);
mayor que la capacidad de defensa de la unidad defensor,
return this;
entonces el ganador del combate es el atacante (return atacante),
}
en caso contrario el ganador del combate es el defensor (return
}
defensor).
...
o Ejercicio 3: Adapta el siguiente código para probar las clases anteriores:
}
Public class Main{
Unidad p = new Escudo( new Soldado("mi_unidad") );
-35-
-36-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
...
Unidad mi_unidad = new Pistola(p);
mi_unidad = ((Complemento) mi_unidad)
.suprime_complemento((Complemento) p);
}
abstract class Complemento extends Unidad {
...
Opción 2: Tratamiento uniforme de Unidades y Complementos:
protected abstract String tipo();
abstract class Unidad {
public Unidad suprime_complemento(String cual) {
...
if (tipo().equals(cual))
public Unidad suprime_complemento(Unidad complemento) {
return _sujeto;
return this; }
else {
...
_sujeto = _sujeto.suprime_complemento(cual);
}
return this;
abstract class Complemento extends Unidad {
}
...
public Unidad suprime_complemento(Unidad complemento) {
if (complemento == this)
return _sujeto;
...
}
class Escudo extends Complemento {
...
else {
protected String tipo() { return "ESCUDO"; }
_sujeto =
...
_sujeto.suprime_complemento(complemento);
return this;
}
class Pistola extends Complemento {
}
...
}
protected String tipo() { return "PISTOLA"; }
...
...
}
Unidad p = new Escudo( new Soldado("mi_unidad") );
}
Unidad mi_unidad = new Pistola(p);
mi_unidad = mi_unidad.suprime_complemento(p);
o Ejercicio 5: Si se desease pasar como parámetro un identificador del tipo
de complemento que se desea suprimir al método suprimirComplemento
Unidad mi_unidad = new Pistola(new Escudo(new
Soldado("mi_unidad")));
mi_unidad = mi_unidad.suprime_complemento("ESCUDO");
¿cómo habría que modificar la implementación anterior?.
Nota: En ocasiones nos puede interesar tener identificado el
abstract class Unidad {
complemento que se manipula por ejemplo para borrarlo. Por
...
public Unidad suprime_complemento(String cual) { return this; }
-37-
ejemplo si una Unidad dispone de dos pistolas igual nos interesa
-38-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
eliminar la que adquirió en primer lugar y no una cualquiera de
ellas (como lo hace el método anterior.). En este caso en el
constructor
del
complemento
será
necesario
indicar
un
identificador.
Patrón Facade o Fachada
•
Clasificación: Estructural.
•
Propósito: Proporcionar una interfaz única para un conjunto de interfaces en un
subsistema. El objetivo es definir la interfaz de nivel más alto de las operaciones
que realiza el subsistema para que sea más sencillo el usarlo por otros módulos o
subsistemas diferentes, es decir facilitar el acceso.
•
o Solución 2: Usar el compilador como una caja negra de modo que los
Motivación:
cambios en la estructura del compilador o sus interfaces internas no
o En general la división de un sistema complejo en subsistemas facilita el
afecten, es decir no se propaguen más allá del punto de conexión que se
poder abordar el problema y reduce la complejidad.
proporciona que será la fachada.
o El objetivo que se persigue es minimizar las comunicaciones y puntos de
acceso de un subsistema a otro de modo que la dependencia entre
subsistemas se reduzca. Es decir, disminuir el acoplamiento entre
sistemas.
o Problema: En el contexto del desarrollo de un entorno de programación
integrado por ejemplo para el lenguaje C++; se desea disponer de una
herramienta debuger por lo que se requerirá hacer uso de un compilador.
o Solución 1: Conocer los diferentes módulos y componentes del
compilador (Scanner, Parser, etc.) de modo que pueda hacer llamadas a
cada uno de ellos.
o Así se reducen las dependencias entre los módulos y se aisla a los
posibles clientes de los cambios internos del módulo. Sin embargo el
emplear una fachada no impide que existan aplicaciones especializadas
que puedan acceder a las clases del módulo directamente, es decir la
fachada no oculta las funcionalidades de más bajo nivel.
•
-39-
Aplicabilidad:
-40-
Patrones de diseño
Máster en Bases de Datos e Internet
o Necesidad de una interfaz más simple para un subsistema complejo
Patrones de diseño
•
Colaboraciones entre participantes: Los clientes se comunican con el
debido a que algunos clientes no necesitan conocer todo. Es decir a los
subsistema enviando peticiones a la fachada, la cual redirige las peticiones a los
clientes sólo se le proporciona aquello que necesitan. La fachada
objetos apropiados. Aunque las clases del subsistema son las que realizan el
proporciona un punto de vista simple por defecto del subsistema y sólo
trabajo real, la fachada puede tener que realizar alguna operación por si misma
los clientes que necesiten mayor grado de personalización accederán
como por ejemplo traducir sus interfaces a las interfaces del subsystema
directamente al subsistema sin hacerlo mediante la fachada.
(delegación y adaptación de protocolos).
o Necesidad de reducir las dependencias entre las clases que implementan
•
Consecuencias:
un subsistema y sus clientes. Es decir, intentar acotar que un cambio en
o Reduce el acomplamiento entre clientes y subsistemas facilitando su uso
el subsistema no se propague al exterior promoviendo la independencia
y aislando la implementación de modo que se pueden realizar cambios en
de los subsistemas y su portabilidad.
esta sin alterar el cliente. Además se reduce el número de objetos que el
o Estructuración en capas de los subsistemas, de modo que cada fachada se
cliente debe conocer.
corresponde con un punto de entrada a cada nivel.
•
Máster en Bases de Datos e Internet
o Los objetos del subsistema no conocen a la fachada por lo que es posible
tener diferentes fachadas que proporcionen acceso a diferentes tipos
Estructura:
(perfiles) de usuario.
o No impide que los clientes accedan a las clases del subsistema si resulta
necesario.
•
Implementación:
o La reducción del acoplamiento entre clientes y subsistemas puede
reducirse incluso más si en lugar de emplear una fachada concreta la
fachada es una clase abstracta de la que se proporcionan diferentes
implementaciones del subsistema. Para instanciar una fachada en
•
concreto para un determinado cliente se debería usar una factoría.
Participantes:
o Fachada o Facade (Compiler): Conoce las clases del subsistema
•
Patrones relacionados:
responsables de una determinada operación que se les está ofertando a
o Mediador o Mediator: Al igual que la fachada el mediador abstrae la
los clientes. Cuando un cliente le realiza una petición delega las
funcionalidad de clases existentes. Sin embargo, el propósito del
peticiones en los objetos apropiados del subsistema; es decir, las clases
mediador es abstraer las comunicaciones arbitrarias que se producen
realizan el proceso, la fachada no asume la responsabilidad.
entre los objetos del subsistema centralizando a menudo una determinada
etc.):
funcionalidad que no pertenece a ningún otro objeto del subsistema.
Implementan la funcionalidad del subsistema realizando el trabajo
Además en el patrón mediador las clases del subsistema conocen a la
solicitado por la Fachada. Estas clases no conocen la existencia de la
clase mediadora y realizan la comunicación con el mediador en lugar de
Fachada (no tienen referencias a la fachada).
hacerlo unas con otras directamente. Por el contrario los objetos del
o Clases
del
subsistema
(Scanner,
-41-
Parser,
ProgramNode,
-42-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
subsistema no tienen conocimiento de la fachada y esta no define nueva
Máster en Bases de Datos e Internet
o Solución 2: Separar en jerarquías diferentes la abstracción de la ventana
funcionalidad.
y sus implementaciones dependientes de la plataforma.
o Instancia única o Singleton: En general sólo es necesario disponer de un
objeto fachada (si en la fachada no se almacena estado) por lo tanto se
suele usar este patrón en combinación con el patrón instancia única.
Patrón Bridge o Puente
•
Clasificación: Estructural.
•
Propósito: Desacoplar una abstracción de su implementación de forma que cada
una de ellas pueda variar independientemente.
•
Motivación:
o En general para realizar la implementación de abstracciones se suele
emplear la herencia. El problema que genera la herencia es que asocia de
o De este modo todas las operaciones utilizadas en las subclases de
forma permanente la implementación y la abstracción.
Windows se definen como métodos abstractos de la Interfaz WindowImp
o Problema: En un entorno de ventanas que puede funcionar en dos
sistemas de ventanas diferentes (por ejemplo Windows y Mac), la
(puente o brige).
•
abstracción “Ventana” permite desarrollar aplicaciones que funcionen en
o Desacoplar abstracciones de sus implementaciones permitiendo el
los dos sistemas pero la implementación de esta abstracción deberá ser
cambio en tiempo de ejecución.
distinta en uno que en otro.
o Necesidad de extender mediante herencia tanto la abstracción como sus
o Solución 1: La solución directa sería implementar la clase abstracta
implementaciones.
“Ventana” con subclases que implementen la abstracción en cada
o El cambio en la implementación de una abstracción no debería afectar a
entorno. Esta solución genera los siguientes problemas:
los clientes.
Es complejo poder extender la abstracción porque implica
o Necesidad de compartir una misma implementación.
modificar cada una de las subclases.
Existen problemas de dependencia de la plataforma.
-43-
Aplicabilidad:
•
Estructura:
-44-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
Si la abstracción conoce la jerarquía de implementadores
entonces puede crear el implementador en el constructor en base
a sus parámetros.
Si la abstracción no conoce la jerarquía de implementadores
entonces deberá delegar en otro objeto que se encargue de
proporcionarle el implementador concreto, por ejemplo una
Factoría.
o Compartición de implementadores.
o Herencia múltiple.
•
Participantes:
o Abstracción (Abstraction): Define la interfaz de la abstracción y
mantiene la referencia al objeto implementador.
o Abstracción refinada (RefinedAbstraction): Extiende la interfaz definida
Patrón Adapter o Adaptador
•
Clasificación: Estructural.
•
Propósito: El adaptador o wrapper permite la colaboración entre clases con
interfaces incompatibles.
por la abstracción.
o Implementador
(Implementor):
Define
la
interfaz
para
los
implementadores concretos. Esta interfaz no tiene porque corresponderse
con
la
interfaz
de
la
abstracción
(Implementador->primitivas,
Abstracción->operaciones de alto nivel).
o Implementador concreto (ConcreteImplementorX)
•
Colaboraciones entre participantes:
o La abstracción redirige peticiones del cliente al objeto implementador.
•
Motivación:
o Reutilizar clases con interfaces incompatibles.
o Problema: En el contexto de un editor gráfico se manipulan objetos que
cumplen una determinada interfaz (Shape). Esta interfaz abstrae a:
Clases elementales como por ejemplo líneas y polígonos
sencillos.
Clases relativas a la edición de texto no básica.
Además se pretende reutilizar la clase existente de otra librería
Consecuencias:
o Desacoplamiento entre interfaz e implementación.
Elimina dependencias de compilación.
Posibilidad de configuración en tiempo de ejecución.
o Facilita el poder extender independientemente las jerarquías de
abstracción e implementación.
o Oculta los detalles de implementación a los clientes.
•
•
(TextView), pero inicialmente esta librería no fue diseñada teniendo en
cuenta la interfaz Shape.
o Solución 1: Modificar la clase TextView para que cumpla la interfaz
Shape. Esta solución en general es inaceptable porque esto puede
implicar alterar otras aplicaciones en funcionamiento o duplicar código.
o Solución 2: Emplear un adaptador.
Implementación:
o Único implementador.
o Creación del objeto implementador.
-45-
-46-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Aplicabilidad:
Patrones de diseño
•
o Se desea emplear una clase existente que no es compatible con el interfaz
Participantes:
o Objetivo o Target: Define la interfaz dependiente del dominio usada por
que se le requiere.
el cliente.
o Se desea crear una clase reusable que coopere con clases no relacionadas.
o Cliente o Client: Colabora con los objetos de acuerdo con el interfaz
o Se desea usar diversas subclases existentes pero resulta impráctico
Objetivo o Target.
adaptar sus interfaces mediante la extensión de todas ellas por lo que se
o Adaptado o Adaptee: Define una interfaz existente que necesita ser
emplea un objeto adaptador de la clase padre.
•
Máster en Bases de Datos e Internet
adaptada.
Estructura:
o Adaptador oAdapter: Adapta la interfaz del adaptado a la interfaz
o Opción 1 (herencia): La clase adaptadora implementa los métodos de la
interfaz pública deseada (Target) e implementa la clase que se desea
adaptar (heredando su métodos).
Objetivo.
•
Colaboraciones entre participantes: El cliente envía mensajes al adaptador y
éste en repuesta los envía al objeto adaptado.
•
Consecuencias:
o En ocasiones, permite la incorporación de funcionalidades no disponibles
en la clase adaptada.
o Clase adaptadora:
No permite adaptar una clase y todas sus subclases.
Si se opta por la opción 1 no existe indirección.
La clase adaptadora permite redefinir parte del comportamiento
o Opción 2 (composición): La clase adaptadora implementa los métodos de
la interfaz pública deseada (Target) y usa un objeto de la clase que se
desea adaptar para delegar parte del trabajo.
del adaptado.
o Objeto adaptador:
Un adaptador permite adaptar a diversos objetos que poseen un
antecesor común.
-47-
-48-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
Difícil cambiar el comportamiento del adaptado. Para ello sería
necesario extender el objeto adaptado y adaptar la nueva
subclase.
Patrón Flyweight o Objeto Ligero
•
Clasificación: Estructural.
•
Propósito: Uso compartido de un gran número de objetos lígeros (o de grano
fíno) para aumentar la eficiencia.
•
Motivación:
o Problema: En el contexto de un editor de documentos se emplean
objetos para representar sus elementos: tablas, figuras, caracteres, etc.
Además se desea tratar a los elementos de forma uniforme. El problema
es que mantener un objeto para cada letra por ejemplo puede ser muy
caro.
El objeto ligero o flyweight actúa como un objeto independiente
que no se diferencia del objeto compartido.
Distinción en el estado del objeto ligero (por ejemplo el formato
de la letra o el carácter que se representa):
Estado intrínsico: El estado se almacena dentro del objeto
ligero e independientemente del contexto en el que se usa.
(La letra que se representa)
o Solución 1: Tratar los caracteres de forma especial, es decir dar un
tratamiento específico para los caracteres en los diferentes algoritmos.
o Solución 2: Compartir objetos que pueden usarse al mismo tiempo en
diferentes contextos. A estos objetos los denominaremos objetos ligeros
o flyweight.
Estado extrínsico: El estado depende del contexto en el
que se encuentra el objeto de modo que el objeto ligero no
puede ser compartido. (La posición y el formato o el estilo
que se le da al caracter).
Los clientes del objeto ligero son los responsables de
proporcionar el estado extrínseco al objeto ligero cuando lo
necesite.
-49-
-50-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
•
Aplicabilidad:
objetos ligeros reciben y actúan sobre el estado extrínseco.
Existe un gran número de los objetos que se desean compartir.
o ObjetoLigeroConcreto o ConcreteFlyweight: Implementa la interfaz del
El coste de almacenamiento es alto debido a la gran cantidad de
objeto ligero añadiendo el estado intrínseco.
objetos que se requieren.
o ObjetoLigeroNoCompartido o UnsharedConcreteFlyweight: Puede hacer
La mayor parte del estado puede hacerse extrínsico.
grupos
de
objetos
pueden
reemplazarse
objetos con la interfaz de objeto ligero que no se compartan. En general
por
estos objetos contienen a otros objetos ligeros (fila, columna, etc.).
relativamente pocos objetos compartidos al eliminar el estado
o FábricaDeObjetosLigeros o FlyweightFactory: Crea y gestiona los
extrínsico.
objetos ligerso y asegura la correcta compartición de los objetos ligeros.
No se depende de la identidad entre objetos.
•
Participantes:
o ObjetoLigero o Flyweight: Declara la interfaz mediante la cual los
o Si se desea compartir objetos y se cumplen las siguientes condiciones:
Muchos
Máster en Bases de Datos e Internet
o Cliente o Client: Mantiene referencias a objetos ligeros y calcula (o
almacena) el estdo extrínsico de los objetos ligeros.
Estructura:
•
Colaboraciones entre participantes:
o El estado extrínsico es almacenado o calculado por lo clientes y
proporcionado a los objetos ligeros cuando estos lo necesitan.
o Los clientes no instancian directamente los objetos ligeros, sino que
delegan esta responsabilidad en la fábrica de objetos ligeros para la
correcta gestión de la compartición de estos.
•
Consecuencias:
o Penalización en el cálculo del estado extrínseco.
o Reducción en los costes de almacenamiento, puesto que se reduce el
número total de instancias y se almacena un solo estado intrínseco por
objeto.
•
-51-
Implementación:
-52-
Patrones de diseño
Máster en Bases de Datos e Internet
o Eliminar el estado extrínsico.
o Gestión de los objetos compartidos.
o Combinación con el patrón Composición o Composite para construir
grafos dirigidos acíclicos.
Patrones de diseño
Máster en Bases de Datos e Internet
PATRONES DE CREACIÓN
Patrón Prototype o Prototipo
•
Clasificación: Patrón de creación porque de forma transparente (sin necesidad
de conecer la estructura de las instancias) crea objetos.
Los objetos ligeros no pueden tener un enlace al padre porque
dependen del contexto (estado extrínseco).
•
Propósito: Especificar la clase de objetos a crear mediante la clonación de un
prototipo u objeto ya instanciado.
•
Motivación:
o En el contexto de la construcción de un editor gráfico que se plantea en
el inicio del curso. Entre otras opciones, existen unas herramientas
(GraphicTool) que permiten crear objetos nuevos (rectángulo, círculos,
…). Los objetos creados pertenecen a una jerarquía de objetos (Graphic
o Figura) cuyas clases derivadas son particulares para la aplicación.
o Además de la jerarquía de objetos Graphic o figura existe una jerarquía
de herramientas (Tool) que debería ser aplicable en otras aplicaciones
como por ejemplo Mover, Rotar, Crear objetos nuevos, etc. Nótese que
podría existir una fachada que nos proporcionase las operaciones de
mover, rotar etc. y nos ocultase la jerarquía de herramientas.
o Problema 1: Las herramientas encargadas de crear los objetos nuevos
deben conocer las clases concretas de los objetos que van a instanciar
puesto que pertenecean a la jerarquía de figuras y son particulares para la
aplicación del editor gráfico.
o Problema 2: Si tenemos una acción (subclase herramienta) para crear un
rectángulo, tendremos que tener otra para crear un círculo, etc. Por lo
tanto si existen 200 objetos diferentes tendremos 200 clases de acción.
o Solución: En primer lugar establecer sólo una clase que se encargue de la
creación de los objetos de la jerarquía (todas las instancias). Para que
además la herramienta de creación no tenga que conocer a todos los
posibles tipos de instancia de la jerarquía, la herramienta de creación va a
construir los nuevos objetos de forma indirecta. Es decir la herramienta
de creación se inicializa con una instancia de las subclases gráfica y es a
las subclases gráficas a las que le corresonde obtener una copia de sí
mismas si se desea crear objetos de ese tipo.
-53-
-54-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o PrototipoConcretoX o ConcretPrototypeX: Implementa la operación de
clonarse.
o Cliente o Client: Crea un nuevo objeto solicitándole al prototipo que se
clone.
•
Colaboraciones entre participantes: El cliente solicita a un objeto prototipo
que se replique (que se clone), es decir que se cree una copia de si mismo.
•
Consecuencias:
o Oculta las clases del producto al cliente.
o Permite que el cliente trabaje con clases dependientes de la aplicación sin
cambios en este.
o Especificación de nuevos objetos mediante el cambio de sus valores.
Nótese el método que hay que introducir en la superclase Graphic para
o Especificación de nuevos objetos mediante la variación de su estructura
permitir la réplica de los objetos.
•
mediante el cambio del prototipo de modo que el cliente no se vea
Aplicabilidad:
afectado.
o Cuando un sistema debe ser independiente de la forma en que sus
o Reducción del número de subclases. El patrón prototipo te permite a ti
productos son creados, compuestos y representados y …:
instanciar un nuevo clon a partir del prototipo en vez de pedir al método
Las clases a instanciar son específicas en tiempo de ejecución.
de fabricación que cree una nueva instancia, por lo tanto no necesitas una
Sólo existe un número pequeño de combinaciones diferentes de
jerarquía de clases creadoras.
estado para las instancias de una clase.
•
o Configuración dinámica de una aplicación. Es posible añadir y eliminar
Estructura:
productos en tiempo de ejecución. Algunos entornos en tiempo de
ejecución te premiten la carga de clases de forma dinámica. El patrón
prototipo es la clave para explotar tales facilidades. (Ejemplo: Creación
del botón casa)
•
Implementación:
o Uso de un gestor de prototipos. En este patrón surge el problema de
quién crea los prototipos para proporcionárselos al cliente de modo que
este no sea dependiente de las jerarquías. En general debe ser un objeto
que tenga que conocer la jerarquía y se la proporcione a los clientes
•
(puede haber más de uno), este objeto se conoce como el gestor de
Participantes:
prototipos. El gestor de prototipos tiene que proporcionar al cliente
o Prototipo o Prototype: Declara la interfaz para clonarse.
métodos para que el cliente seleccione el prototipo que estime oportuno,
por
-55-
ejemplo
un
método
-56-
Producto
crea(String
tipoObjeto,
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
otraInformación);. Si en lugar de pasar un simple String con un nombre
o Ejercicio 3: Buscar información de la interfaz java Cloneable y modificar
se establecen especificaciones más complejas el patrón prototipo
el ejemplo proporcionado para usarla en lugar de emplear el método
degenerará en el patrón Negociador de productos o Product Traider en
clonar().
donde el negociador es un gestor de prototipos.
Cliente
o Ejercicio 4: Modificar el ejemplo propocionado para permitir objetos
compuestos. Usar el patrón composición.
Negociador
Patrón Singleton o Instancia Única
Especifiación
Producto
•
Clasificación: Creacional.
•
Propósito: Se asegura de que una determinada clase sólo tiene una instancia y
proporciona un punto de acceso a dicha instancia.
o Implementación de la operación de clonación. En los objetos compuestos
esto puede ser un problema. Por ejemplo si clonamos un objeto decorado
•
(ver patrón decorador) de qué se hace copia del envoltorio exterior o de
o Existen múltiples ejemplos en donde sólo se requiere tener una instancia
todo el conjunto, es decir copia las referencias o crea nuevos objetos para
de una clase, por ejemplo en el caso del patrón anterior sólo
el estado. En función de la decisión que se tome se modificará la
necesistaremos una instancia del gestor de prototipos, o si tenemos
operación clonar().
muchas impresoras en general sólo necesitaremos un único gestor de
impresión, muchas conexiones pero un único gestor de conexión etc.
o Inicialización del objeto clonado en caso de que la réplica necesite una
inicialización adicional. A veces no es factible crear la instancia y
o Problema: Nos interesa facilitar el acceso a ese objeto y que ese objeto
replicar todo el estado del objeto que sirve como prototipo por ejemplo
sea único, es decir exista una sola instancia de un determinado tipo de
en el caso de que el prototipo tenga una clave o identificador de instancia
clase.
o Solución 1: Mantener una variable global para facilitar el acceso. De este
o si hay una cierta parte del prototipo que no se puede clonar. Cuando se
modo no resolvemos el problema porque siempre podemos instanciar
requiere inicialización la opción más común:
Exportar a la superclase los métodos de inicialización. Esta
múltiples objetos en variables locales aunque si es cierto que es de fácil
opción es válida si todas las figuras en la jerarquía tuviesen la
acceso.
o Solución 2: Hacer responsable a la propia clase de la instancia única:
misma interfaz para realizar su inicialización. Ejemplo void
•
Motivación:
inicializar (string fichxml). Cada subclase debe redefinir el
Restringiendo el acceso al constructor de modo que una vez
método y extraer la información necesaria.
creada una instancia ya no se puedan crear más.
Proporcionando un mecanismo para acceder a la instancia si esta
Ejercicios:
ya ha sido creada y sino que la cree en ese momento.
o Ejercicio 1: Realiza un diagrama de objetos del código que se
proporciona de ejemplo.
•
o Ejercicio 2: Realiza un diagrama de secuencia del programa Main.
Aplicabilidad:
o Debe existir una única instancia de una clase, y ésta debe ser accesible a
los clientes desde un punto de acceso bien conocido.
-57-
-58-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o La única instancia puede ser extendida (subclase), y los clientes deberían
o En Java:
poder usar la instancia extendida sin modificar su código.
•
Máster en Bases de Datos e Internet
Declarar el constructor como privado y además establecer un
atributo como privado para almacenar la instancia. Para
Estructura:
inicializar el atributo privado emplear un bloque estático.
Establecer un método público que proporcione la instancia
correspondiente al atributo privado de la clase.
•
Ejercicios:
o Ejercicio 1: Probar el ejemplo de código proporcionado para el patrón
Instancia única y analizarlo.
•
Participantes:
Patrón Factory Method o Fabricación
o Instancia única o Singleton: Define un método de clase que permite a los
•
Clasificación: Creacional.
clientes acceder a la instancia única y normalmente también es la
•
Propósito: Define la interfaz para crear un objeto, pero deja que las subclases
responsable de crear su única instancia.
•
Colaboraciones entre participantes: Los clientes acceden a la instancia del
Singleton a través de la operación definida a tal fin (instance()).
•
Consecuencias:
•
Motivación:
o Framework para apliacaciones que permiten presentar múltiples
documentos al usuario; donde existen dos abstracciones: Aplicación y
o Acceso controlado a la instancia única.
Documento. Para una aplicación específica, se especializan las interfaces
o Reduce el espacio de nombres al evitar variables globales.
Aplicación y Documento.
o Permite el refinamiento de operaciones y representación mediante el uso
o Problema: La abstracción (o interfaz) Aplicación conoce cuándo se debe
de herencia. En este caso en lugar de tener una única instancia única de
crear un documento pero no qué documento crear puesto que eso
ella misma tiene una instancia única de una subclase. En este caso se usa
depende de la aplicación específica que se desarrolla empleando el
la instancia de la subclase con la interfaz de la superclase.
framework, por ejemplo un documento de Word o un documento de
o Permite un número variable de instancias.
o Más flexible que las operaciones de clase.
•
decidan que clase concreta se debe instanciar.
texto.
o Solución 1: Dar en la superclase o clase abstracta una implementación
por defecto del método crear documento y que las subclases lo redefinan.
Implementación:
o Asegurar la unicidad de la instancia de la clase.
o Extender la clase InstanciaUnica o Singleton:
El método de clase instacia conoce las subclases de la jerarquía y
crea la instancia deseada.
Establecer algún mecanismo para registrar las subclases.
-59-
Esta solución tiene la siguiente desventaja:
Puede ser que por cada aplicación concreta necesitemos un tipo
de documento concreto por lo que la subclase de documento por
defecto puede no ser nunca empleada.
o Solución 2: Usar el patrón prototipo, pero esto requiere que la jerarquía
de productos colabore.
-60-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Solución 3: Asigna a un método abstracto la responsabilidad de crear un
Máster en Bases de Datos e Internet
o CreadorConcreto
documento concreto, separando esta responsabilidad del framework.
o
ConcreteCreator
o
FactoríaConcreta
o
ConcreteFactory: Redefine el método de fabricación para devolver una
instancia de un producto concreto.
•
Colaboraciones entre participantes: El creador emplea el método de
fabricación redefinido por sus sublcases para utilizar la instancia del producto
concreto apropiada.
•
Consecuencias:
o Elimina la necesidad de incluir clases específicas de la aplicación en
código más general dando mayor potencia de reutilización del
•
Aplicabilidad:
framework.
o No se puede anticipar la clase de objetos que se tienen que crear.
o Mayor flexibilidad dado que se proporciona un mecanismo a las
subclases para introducir una versión másextendida del producto.
o Una clase quiere que sus subclases especifiquen que objetos se deben
crear.
o Conecta jerarquías paralelas.
o Clases que delegan la responsabilidad a una de las subclases
o Desventaja: Puede obligar a extender la clase creadora sólo para crear un
colaboradoras y se desea localizar el conocimiento de qué sublcases es la
producto concreto. Si esto es un problema puede emplear otra solución
encargada.
como por ejemplo el patrón prototipo.
•
Estructura:
•
Participantes:
o Producto o Product: Definde la interfaz de los objetos creados por el
método de fabricación.
o ProductoConcreto o ConcreteProduct: Implementa la interfaz de los
productos.
•
Implementación:
o Dos variantes:
o Creador o Creator o Factoría o Factory: Declara el método de
fabricación y opcionalmente pudede definir una implementación por
defecto que construye un producto concreto. Puede utilizar el método de
fabricación.
-61-
El
creador
es
una
clase
abstracta
y
no
proporciona
implementación por defecto para el método (necesario extender al
creador)
-62-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
El creador es una clase concreta y define un producto concreto
por defecto (flexibilidad para cambios futuros).
o Métodos de fabricación parametrizados.
Un único método puede crear distintos productos en base a los
parámetros del método de fabricación. (Solución más común.).
•
Ejercicios:
o Ejercicio 1: Probar el ejemplo de código proporcionado para el patrón
•
fabricación y analizarlo.
Aplicabilidad:
o Un sistema debe ser independiente de la forma en que sus productos son
Patrón Abstract Factory o Fábrica Abstracta
•
Clasificación: Creacional.
•
Propósito: Interfaz para la creación de familias de objetos relacionados sin
creados, compuestos y representados.
o Un sistema debe ser configurado con una de muchas familias de
productos disponibles.
especificar sus clases concretas.
•
o Una familia de productos son diseñados para su uso conjunto, y se
requiere asegurar este uso conjunto.
Motivación:
o Se desea proporcionar una biblioteca de productos presentando su
o Interfaz de usuario con múltiples look-and-feels (Motif, Presentation
interfz, pero no su implementación.
Manager, Windows, ...)
o Cada Look-and-feel define su propio juego de components (widgets:
•
Estructura:
•
Participantes:
botones, ventanas, barras de desplazamiento, ...)
o Problema: Por razones de portabilidad el resto del sistema no debe hacer
referencia a componenetes concretos.
o Solución: Crear una clase abstracta con un método de fabricación para
cada componente (fábrica abstracta) y una clase abstracta por
componente. El cliente creará los componentes mediante la fábrica
abstracta. De modo que la fábrica de componentes garantiza el uso
consistente de cmponentes de un mismo look-and-feel.
o Fábrica abstracta o AbstractFactory: Declara la interfaz para las
operaciones que crean productos abstractos (métodos de fabricación)
o Fábrica Concreta o ConcretFactory: Implementa los métodos de
fabricación de productos concretos.
o Producto abstracto o AbstractProduct: Declara la interfaz utilizada por el
cliente par un tipo de producto concreto.
-63-
-64-
Patrones de diseño
Máster en Bases de Datos e Internet
o ProductoConcreto o ConcreteProduct: Define un producto creado por el
Patrones de diseño
•
de modo que el mismo proceso de construcción permite crear diferentes
del producto abstracto.
representaciones.
•
abstracta y los productos abstractos.
Motivación:
o Lector de documentos en formato RTF que lo convierte a diferentes
Colaboraciones entre participantes: Normalmente se crea una única fábrica
formatos (ASCII; TEX;...).
concreta que se encarga de crear los productos concretos, mientras que la fábrica
o Dejar abierta la posibilidad de nuevos tipos de conversión: debería ser
abstracta difiere la creación de productos a sus subclases.
•
Propósito: Separa la construcción de un objeto complejo de su representaicón,
método de fabricación de una fábrica concreta. Implementa la interfaz
o Cliente o Client: Usa sólo las interfaces declaradas por la fábrica
•
Máster en Bases de Datos e Internet
sencillo añadir una nueva conversión sin modificar el lector.
Consecuencias:
o Solución: Configurar el lector con un objeto responsable de convertir
o Aísla clases concretas (no aparecen en el código del cliente).
cada fragmento del documento RTF al formato destino.
o Facilita el intercambio de familias de productos.
o Las subclases de la clase constructora especializan la construcción para
los distintos formatos
o Simplifica consistencia entre productos.
o Difícil añadir nuevas clases de productos.
•
Implementación:
o Las fábricas usualmente suelen se instancias únicas.
o La creación de productos puede realizarse por el método de fabricación
habitual o mediante el patrón prototipo para evitar extender la fábrica
abstracta.
o Flexibilizar la fábrica mediante la parametrización del método de
fabricación:
El método de fabricación puede crear diferentes tipos de
componenetes en base a los parámetros del método.
•
Aplicabilidad:
o El algoritmo para crear un objeto complejo debe ser independiente de las
El cliente debe realizar una conversión tras crear el producto
partes que constituyen el objeto y de cómo son ensambladas.
(downcasting).
o El proceso de construcción debe premitir distintas representaciones del
En la mayoría de los lenguajes no hay ninguna relación formal
objeto construido.
entre valores de los parámetros y productos creados, exceptuando
el código fuente.
•
Estructura:
Patrón Builder o Constructor
•
Clasificación: Creacional.
-65-
-66-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
Participantes:
o Constructor o Builder: Especifica la interfaz para la creación de las
partes de un Producto.
o ConstructorConcreto o ConcreteBuilder: Implementa la interfaz del
constructor para construir y ensamblar las diferentes partes del producto.
Además almacena el producto en construcción y proporciona una
interfaz para recuperar el producto construido.
o Director o Director: Construye un objeto utilizando la interfaz del
constructor.
o Producto o Product: Objeto concreto a construir.
•
•
Consecuencias:
o Permite variar la representación interna de un producto.
o Aísla el código de la construcción y la representación.
o Proporciona un control más detallado del proceso de construcción.
Colaboraciones entre participantes:
o El cliente crea el objeto director y lo configura con el constructor
deseado.
o El director notifica al constructor la parte del producto que debe ser
creada.
o El constructor añade partes al producto, de acuerdo con las peticiones del
director.
o El cliente recupera el producto final del constructor.
-67-
-68-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
PATRONES DE COMPORTAMIENTO
Patrón Chain of Responsability o Cadena de Responsabilidad
•
Clasificación: De comportamiento porque determina como se debe realizar el
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
Propósito: Posibilidad de enviar (y/o gestionar) una petición a más de un objeto
mediante el encadenamiento de los receptores.
•
o La alternativa a al solución de la cadena de responsabilidad es que cada
Motivación:
o Sistema de ayuda sensible al contexto de una interfaz gráfica donde el
usuario puede solicitar ayuda de cualquier componente o parte de la
interfaz. Si la parte seleccionada tienen información específica debe
presentarla, en caso contrario debe presentar un mensaje relacionado con
el contexto más próximo (sucesor) de la parte seleccionada. En general el
contexto más próximo será el que lo contiene el elemento.
o Problema: El objeto que inicia la petición no conoce a priori que objeto
proporciona la ayuda, es decir no sabe si su sucesor más cercano
objeto conociese la forma de resolver el servicio. Esto implicaría
sobrecargar el objeto en concreto con más cosas de las necesarias y
llevaría en muchos casos a la duplicidad de código. Otra solución sería
conocer a priori el objeto que resuelve la petición pero esto último
provoca acoplamiento entre el que inicia el servicio y el que lo resuelve,
por lo cual es más difícil de mantener. El patrón está pensado para que la
estructura de la cadena pueda variar dinámicamente y que además el
mensaje pueda ir modificándose.
resolverá la petición o será otro más alejado.
o Solución: Desacoplar el emisor de la petición de los receptores (receptor
implícito, es decir el que realmente resuelve la petición). Se establece
una cadena de objetos que delegan la petición hasta que uno se hace
cargo. Por lo tanto la respuesta a la petición dependerá tanto del
componente en que se realice la petición como del contexto en que se
encuentre éste.
o Para realizar la delegación entre objetos de la cadena es necesario tener
una estructura que los relacione por ejemplo la asociación manejador o
handler.
-69-
-70-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
o Cuando un cliente inicia una petición, dicha petición se propaga a través
Aplicabilidad:
de la caden hasta que un manejador concreto asume la responsabilidad de
o Más de un objeto puede manejar la petición y no se conoce a priori cuál
gestionarla y en ese momento corta la cadena de responsabilidad.
de ellos va a resolverla.
o No se desea identificar explícitamente el receptor de una petición, sino
•
que le envías la petición a un conjunto.
Consecuencias:
o Reduce el acoplamiento entre objetos, puesto que reduce las
dependencias. En cualquier caso al mismo tiempo acarrea una pequeña
o Los objetos que pueden manejar la petición varían dinámicamente.
•
Máster en Bases de Datos e Internet
penalización de la eficiencia por los niveles de indirección introducidos
Estructura:
que son más acusados cuanto mayor sea la delegación en la cadena.
o Flexibilidad añadida a la hora de asignar responsabilidades a los objetos.
o La recepción de la petición no está garantizada puesto que quizás ningún
objeto de la cadena de responsabilidad resuelve el servicio. Por lo tanto
es necesario saber cuál es el final de la cadena de responsabilidad y si en
ese momento no se puede resolver la petición devolver algún tipo de
error, mensaje informativo o valor por defecto.
•
Implementación:
o Cadena de sucesores: Definir nuevos enlaces para los sucesores o
emplear enlaces existentes como por ejemplo los definidos en el patrón
composición con variante para referenciar el padre. En general si no
exiten enlaces para los sucesores se crea una asociación en la superclase
de los objetos que intervienen en la cadena. Esta superclase y asociación
•
permite establecer el código para realizar la asociación y delegación de la
Participantes:
o Manejador o Handler: Define la interfaz para manejar peticiones y
normalmente también define el enlace al sucesor en la cadena. En
general también determina la resolución por defecto de la petición sino
existe un objeto en quien delegar.
o ManejadorConcreto o ConcreteHandler: Maneja las peticiones de las
quiere manejar la petición deber reescribir el método correspondiente,
sino actuará como la superclase.
o Conexión de sucesores.
o Representación de las peticiones.
que es responsable. Si no puede gestionar la petición, la redirige a su
Un método por tipo de petición.
sucesor.
Único método parametrizado para distinguir diferentes tipos de
o Cliente o Client: Envía una petición a algún manejador concreto de la
peticiones:
Como parámetro del método poner un id que nos indique
cadena.
•
petición en la superclase de modo que cada una de las clases concretas si
Colaboraciones entre participantes:
el tipo de petición. Mala solución porque si alguna de las
peticiones implica parámetros entonces a parte de ese
-71-
-72-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
identificador tendríamos que poner en cualquier petición
de modo distinto en base a su estado interno. Por ejemplo si la conexión
todos los parametros de todas las posibles peticiones que
está Cerrada y se intenta realizar una consulta SQL se producirá un
no usuamos
mensaje de error, sin embargo si el estado de la conexión es Establecida
Tener como parámetro del método que maneja las
nos propocionará los datos correspondientes si realizamos correctamente
peticiones un objeto petición que actúa como superclase
la consulta.
de los diferentes conjuntos de parámetros de las
peticiones.
conexión en distintos estados
o Se están creando objetos artificiales que no tienen
un
o Solución 1: Extender la clase conexión con subclases que representen la
comportamiento
asociado,
solamente
almacenan un conjunto de parámetros.
o No es necesario recompilar las clases de la cadena
que no manejan la petición si se añade una nueva
Problema: Los objetos tienen que cambiar dinámicamente de
clase cuando pasen de un estado a otro.
o Solución 2: Tener una única clase conexión y en cada uno de los
métodos establecer condiciones (switch, case, if, etc.) para determinar
dentro de los métodos lo que se debe hacer en función del estado.
petición. Además así no se sobrecargan esas clases
Problema: Más complejo el código y el mantenimiento de la
con métodos que no saben resolver.
clase.
o Ejercicio 1: Realiza un diagrama de objetos del código que se
proporciona de ejemplo.
o • Solución 3: Introducir una superclase abstracta que representa a los
estados de la conexión de red. La superclase define la interfaz de los
o Ejercicio 2: Realiza un diagrama de secuencia del programa Main.
métodos dependientes del estado. Esta superclase es extendida con
o Ejercicio 3: Fusiona el código del ejemplo de unidades de combate del
subclases que implementan el comportamiento específico de cada uno de
patrón decorador con el código propocionado en este bloque. A
continuación reflexiona sobre las diferencias entre el patrón decorador y
el patrón cadena de responsabilidad.
los estados concretos.
Problema: Tiene el mismo problema que la solución 1.
o Solución 4: La clase conexión mantiene una referencia a un objeto
estado en el que delega el comportamiento dependiente del estado en que
Patrón State o Estado
•
•
•
se encuentra la conexión. El objeto concreto del que mantiene la
Clasificación: De comportamiento porque determina como se debe realizar el
referencia la conexión en un determinado instante representa el estado
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
actual de dicha conexión. Para cambiar de estado simplemente se cambia
Propósito: Permite a un objeto modificar su comportamiento al cambiar su
la asociación entre la clase conexión y un objeto de la clase estado.
estado interno, de modo que “el objeto concreto en apariencia cambia de clase”.
La clase estado es un clase abstracta (es decir que no pueden existir
Motivación:
instancias de dicha clase) que declara un interfaz común a todas las
o Problema: Supongamos que disponemos de una clase que representa
subclases para representar diferentes estados operacionales. Por lo tanto,
una conexión a una base de datos o una conexión de red. Un objeto en
la clase abstracta se extiende con subclases concretas que representan el
concreto de esa clase puede estar en diferentes estados: Establecida,
comporamiento específico en cada uno de los estados operacionales.
Cerrada o Transmitiendo. Al recibir una petición, el objeto se comporta
-73-
-74-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
contexto. En el ejemplo motivador se corresponde con la clase
TCPConection.
o Estado (State): Define una interfaz para encapsular el comportamiento
asociado con un estado particular del contexto. En el ejemplo motivador
se corresponde con la clase TCPState.
o Estados Concretos (ConcreteState): Cada subclase implementa el
comportamiento asociado con un estado del contexto. En el ejemplo
motivador se corresponde con las clases TCPStateStablished, TCPClose
y TCPListen.
Problema: En los métodos dependientes del estado se pueden requerir
•
atributos de la clase TCPConnection:
•
•
o El contexto delega las partes de comportamiento específicos del estado al
Solución a: Pensar la asociación _state como una relación
objeto ConcreteState que tiene asociado en cada momento. Además el
bidireccional. Esta solución suele ser difícil de mantener y
contexto puede pasarse a sí mismo como argumento al objeto estado para
compleja.
manejar una petición. De esta forma, el objeto estado puede acceder a
Solución b: Proporcionar el propio libro como parámetro
información del contexto si esta es requerida.
de llamada a un metodo.
•
•
Colaboraciones entre participantes:
o La configuración de un contexto la puede realizar un cliente con objetos
Aplicabilidad: El comportamiento de un objeto depende de su estado, y dicho
estado pero en general los clientes utilizan el contexto como interfaz, sin
estado puede cambiar en tiempo de ejecución. Además también se puede aplicar
necesidad de manejar objetos estado directamente. Es más una vez el
cuando existen clases con grandes sentencias condicionales múltiples
contexto está configurado inicialmente, el cliente no debería tratar con
dependientes del estado del objeto y donde el estado se representa por 1 o más
los objetos estado directamente. Además en el constructor de la clase
constantes enumeradas.
contexto se puede indicar un estado inicial.
Estructura:
Por otro lado tanto el contexto como los estados concretos pueden
decidir cambiar el estado actual bajo la política concreta de cambio de
estado.
•
Consecuencias:
o Localiza y separa el comportamiento específico de cada estado
facilitando añadir nuevos estados y transiciones pero haciendo que el
modelo sea menos compacto puesto que aumenta el número de clases.
o Encapsula el comportamiento asociado a un estado concreto en un clase
•
particular y deja en la clase contexto sólo operaciones que no dependen
Participantes:
del estado, lo cual facilita el mantenimiento.
o Contexto (Context): Define la interfaz para los clientes. Mantiene una
instancia de un estado concreto que define el estado actual del objeto
-75-
-76-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Hace explícitas las transiciones entre estados, mientras que si se opta por
Máster en Bases de Datos e Internet
o Ejercicio 2: ¿Qué patrón o patrones se están usando en la
codificar el estado con valores internos en la clase contexto y sentencias
implementación del ejemplo además del patrón estado o State?
condicionales esto sería implícito. Es decir, las transiciones entre estados
o Ejercicio
3:
¿Cuál
es
la
visibilidad
del
método
se mostrarían sólo mediante la asignación de determinados valores a
establecerEstado(EstadoLibro estado) de la clase libro? ¿Podría tener
variables.
otra visibilidad? ¿Qué implicaría?
o Bajo ciertas circunstancias, es posible la compartición de objetos estado
por varios objetos contexto. Por ejemplo cuando los objetos estado no
tienen variables instanciadas, es decir el objeto estado es como un “tipo
Patrón Strategy o Instancia Estrategia
•
de datos” (patrón objeto ligero o flyweight).
•
Propósito: Define, encapsula y hace intercambiables a una familia de
o ¿De quién es la responsabilidad de efectuar transición entre estados? Esto
algoritmos, de modo que un algoritmo puede variar independientemente del
no se especifica en el patrón. En general cuando los criterios son fijos los
cliente que lo usa. Además hace intercambiables a los diferentes algoritmos con
cambios de estado suelen ser responsabilidad de la clase contexto. Sin
la misma funcionalidad.
embargo, se puede permitir que las sublcases estado especifiquen su
•
Motivación:
propio estado sucesor. Esto último requiere que las subclases estado
o En el contexto de un editor de textos se dispone de diversos algoritmos
conozcan el objeto contexto y que el contexto disponga de un método
para particionar un texto en líneas (justificado, alineado a izquierda,
que les permita a dichas subclases cambiar su estado actual
alineado a derecha, con palabras partidas, etc. ) siendo deseable separar a
explícitamente.
las clases clientes de las clases algoritmos de partición por las siguientes
o Creación y destrucción de objetos estado.
razones:
Crear y destruir cada vez que es necesario. Posiblemente siendo
Los clientes que incluyen el código para particionar en líneas son
el contexto el que se encargue de esto. Evita crear objetos que no
más grandes y más difíciles de mantener, especialmente si
son frecuentemente usados.
soportan múltiples algortimos de particionamiento.
Crear al principio y no destruir. Esto sólo es posible cuando los
No todos los algoritmos son necesarios en todos los casos. De
estados se conocen a priori y no se van a cambiar en tiempo de
modo que no queremos que los clientes soporten algoritmos que
ejecución. Da lugar a dos relaciones: EstadosPosibles y
no van a necesitar.
EstadoActual.
Es difícil añadir nuevos algoritmos o modificar los existentes si el
Emplear el patrón instancia única para la creación de estados.
algoritmo forma parte del cliente.
o Herencia dinámica.
•
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
Implementación:
Clasificación: De comportamiento porque determina como se debe realizar el
Se produce duplicidad de código si existen diferentes clientes
distintos que requieren el particionamiento de líneas.
Código ejemplo:
o Ejercicio 1: Analiza cuales son los objetos que se porporcionan en el
código de ejemplo y determina cuál es la función de cada uno de ellos.
-77-
o Solución: Definir clases que encapsulan a las diferentes estrategias de
particionamiento en una jerarquí diferente.
-78-
Patrones de diseño
Máster en Bases de Datos e Internet
Cada una de las clases concretas Compositor representan un algoritmo,
Patrones de diseño
•
Estructura:
•
Participantes:
o Contexto (Context): Es el elmento que usa los algoritmos por lo tanto
de modo que el cliente (Composition) puede reemplazar el algoritmo que
va a delegar en la jerarquía. Está configurado con una estrategia concreta
emplea o bien estáticamente o bien dinámicamente.
mediante una referencia al objeto estrategia correspondiente. Puede
Este patrón también es útil cuando el algoritmo con el que se está
definir una interfaz que permita a la estrategia el acceso a sus datos.
trabajando es complejo y requiere muchas estructuras de datos que se
o Estrategia (Strategy): Declara una interfaz com´un para todos los
quieren aislar.
algoritmos soportados. El contexto utiliza este interfaz para invocar el
Se ve que la estructura es similar al patrón anterior (estado) pero los
algoritmo definido por una estrategia concreta.
propósitos por los que surge son distintos. En el patrón estado existe una
o Estrategia Concreta (ConcreteStrategy): Implementa el algoritmo
dependencia mucho más fuerte que en el patrón estrategia puesto que por
ejemplo una conexión no puede existir si no tiene estado asociado pero el
editor puede existir sin un algoritmo de particionamiento de líneas.
utilizando la interfaz definida por la estrategia.
•
para implementar el algoritmo elegido:
Aplicabilidad:
o Muchas
Colaboraciones entre participantes:
o Es necesario el intercambio de información entre Estrategia y Contexto
Además los algoritmos pueden ser usados por otros tipos de clientes.
•
Máster en Bases de Datos e Internet
clases
relacionadas
se
diferencian
únicamente
en
Parámetros de los métodos de la estrategia: En este caso al
su
algoritmo elegido se le pasa sólo la información que necesita para
comportamiento, de modo que aparece una superclase con el
realizar la operación requerida.
comportamiento común y se accede según la interfaz de la superclase.
En ocasiones, como ocurría en el patrón Estado, el contexto se
o Necesarias distintas variantes de un algoritmo.
pasa a sí mismo a la estrategia. Sin embargo si se opta por esta
o Un algoritmo utiliza información que los clientes no deberían conocer. El
opción se está haciendo más difícil la reutilización de los
patrón evita la exposición de estructuras de datos dependientes del
algoritmos en otros puntos debido a que se están uniendo las dos
algoritmo.
jerarquías (la cliente y la de estrategias).
o Una clase define múltiples comportamientos mediante una serie de
o Los clientes del contexto normalmente configuran a éste con una
instrucciones condicionales. En lugar de emplear las estructuras
condicionales, mover el código de dichas estructuras a clases propias
donde se realice la estrategia pertinente.
-79-
estrategia concreta. A partir de ahí, sólo se interactúa con el contexto.
•
Consecuencias:
-80-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o La herencia puede ayudar a factorizar las partes comunes de las familias
Máster en Bases de Datos e Internet
o Ejercicio 1: Analiza cuáles son los objetos que se porporcionan en el
de algoritmos.
código de ejemplo y determina cuál es la función de cada uno de ellos.
o Alternativa a la extensión de contextos cada uno con una estrategia o
o Ejemplo 2: Amplia el código del ejemplo para proporcionar la estrategia
algoritmo. Además al permitir la evolución independiente se obtiene la
de ordenación Quicksort.
posibilidad de realizar cambios dinámicos de algoritmos.
o Reducción de instrucciones condicionales.
o Diferentes opciones de implementación para un mismo algoritmo sin
Patrón Observer u Observador
•
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
modificar el código de la clase.
o Los clientes deben conocer las diferentes estrategias, a diferencia de lo
•
Propósito: Definir una dependencia uno-a-muchos entre objetos de un modelo y
que ocurría en el patrón estado, y en base a la política estratégica decidir
sus vistas de tal forma que cuando el objeto cambie de estado, todos sus objetos
cuál de las estrategias se va a aplicar.
dependientes sean notificados y actualizados automáticamente.
o Existe una pequeña penalización en la comunicación entre estrategia y
contexto, como sucede siempre que se pasa de una clase monolítica a
usar la delegación, puesto que se produce una indirección.
o Incremento del número de objetos.
•
Clasificación: De comportamiento porque determina como se debe realizar el
•
Motivación:
o Las aplicaciones de hoy en día, en general, se dividen en 3 partes o
capas: Vista (interfaz del sistema), Modelo (lógica de la aplicación) y
Almacenamiento o Persistencia (almacena de forma persistente la
inforamción relacionada con el modelo). Estas tres partes tratan de ser lo
Implementación:
o Para la definición de la interfaz entre estrategia y contexto existen tres
formas básicas:
Pasar como parámetro la información necesaria para la estrategia
de forma explícita. Esta es la opción más comúnmente usada.
Pasar como parámetro el contexto y dejar que la estrategia
explícitamente pida la información que necesita. Es la opción
menos usada con el patrón estrategia aunque es común con el
patrón estado.
más independientes posible aunque tienen puntos de conexión. De este
modo se permite cambiar la interfaz gráfica de las aplicaciones (por
ejemplo de escritorio a Web) o el modelo de almacenamiento empleado
(por ejemplo de ficheros XML a una base de datos relacional) sin afectar
a las demás capas.
o En estos casos y otros existe una necesidad de consistencia entre clases
relacionadas pero manteniendo bajo acoplamiento. Por ejemplo: Separar
componentes GUI de los objetos que mantienen los datos de la
aplicación para que sean reutilizables independientemente.
Mantener en la estrategia una referencia al contexto, es decir,
hacer la asociación bidireccional.
o Cuando los objetos estrategia son opcionales cuando se vaya a emplear
una determinada estrategia es necesario realizar la comprobación de si se
dispone de ella. Otra posibilidad es definir en la jerarquía estrategia la
estragegia nula que es la que se asigna por defecto.
•
Código ejemplo:
-81-
-82-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
En este ejemplo sólo se ha considerado una vista pero si hubiese más el
modelo tendría que notificar la actualización a todas las vistas.
Además el modelo debería disponer de métodos para que más vistas
puedan ser añadidas dinámicamente y también eliminadas; por ejemplo,
si se cierra una ventana.
Nótese que el sujeto no es consciente de cuántos observadores van a
estar afectados por un cambio en concreto en su estado, puesto que no
debe saber nada de su aspecto y comportamiento. Lo único que debe
saber el sujeto es que los observadores disponen de un método actualizar
al que debe llamar cuando cambie de estado.
o Solución 1: Se puede pensar que periódicamente los objetos presentación
•
preguntan al objeto subject por su estado y si este ha modificado lo
Aplicabilidad:
o Una abstracción tiene dos aspectos diferentes, uno dependiente del otro.
actualizan.
Encapsular estos aspectos en objetos separados permite su variación y
o Problema: Esto no parece lógico porque se puede llegar a sobrecargar al
reutilización de modo independiente.
objeto subject aunque este cambie con muy poca frecuencia su estado. Es
o Cuando una modificación en el estado de un objeto requiere cambios de
más lógico que cuando se cambie el estado en subject este notifique a
otros, y no se desea conocer cuantos objetos deben ser cambiados.
todos sus observadores el cambio.
o Cuando un objeto debería ser capaz de notificar a otros objetos sin hacer
o Solución 2: El comportamiento de los observadores (hoja de cálculo,
diagrama de barras,...) depende del sujeto observado, que debería
notificar cualquier cambio en su estado. Además el número de
ninguna suposición acerca de los objetos notificados.
•
Estructura:
observadores no está limitado.
*
Modelo
ObtenerEstado()
MetodosCambio()
Vista
Actualizar()
De modo que el comportamiento sería:
:Controlador
:Modelo
CambiarEstado()
-83-
:Vista
Actualizar()
ObtenerEstado()
-84-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o La relación _subject se realiza entre los objetos concretos y no entre las
interfaces, como en el caso de la relación _observers; es decir, la relación
_observers no es bidireccional. Esto tiene que ser necesariamente así
porque el ConcreteObserver tiene que ser capaz de determinar las
características del ConcretSuject que le interesan y cuales no.
Se podría optar por hacer la asociación observadores bidireccional pero
en ese caso en el observador concreto tendríamos que hacer un
downcasting al sujeto concreto.
En cualquier caso la asociación sujeto se puede evitar si en el método
actualizar se pasa como parámetro el sujeto de forma explícita (actualizar
(Sujeto s)) de modo que se crea una dependencia temporal en tiempo de
•
ejecución pero no en tiempo de compilación. Nótese que en este caso
o Abstrae acoplamiento entre sujeto y observador, de modo que se pueden
también es necesario realizar un downcasting.
•
modificar y reusar las jerarquías de sujestos y observadores
independientemente. Además permite la addición de nuvas clases
Participantes:
observadores sin para ello tener que modificar a los sujetos ni a los
o Sujeto (Subject): Conoce a sus observadores y proporciona una interfaz
demás observadores.
para agregar (attach) y eliminar (detach) observadores del propio Sujeto.
o El sujeto no necesita especificar los observadores afectados por un
o Observador (Observer): Define un método utilizado por el Sujeto para
cambio, es decir, cada sujeto sabe que tiene una lista de observadores
notificar cambios en su estado (update).
•
Consecuencias:
o SujetoConcreto (ConcreteSubject): Mantiene el estado de interés para
pero el sujeto concreto no conoce las clases observadores concretos. Por
los observadores concretos. Notificándo a los observadores el cambio en
lo tanto desconoce a cuales de sus observadores le va a afectar un
su estado.
determinado cambio en su estado.
o ObservadorConcreto (ConcreteObserver): Mantiene una referencia al
o Desconocimiento de las consecuencias de una actualización. El sujeto
sujeto concreto debido a que parte de su estado debe permanecer
concreto emite una comunicación broadcast a todos sus observadores y
consistente con el estado del sujeto. Para lograr esta consistencia,
son estos los que preguntan el estado al sujeto concreto y determinan si
implementa la interfaz de actualización.
se modifican o no.
Colaboraciones entre participantes:
•
Implementación:
o El sujeto concreto notifica a sus observadores cada vez que se modifica
o Implementación asociación sujeto-observadores. En un principio la
su estado. Esta responsabilidad de notificar la hereda de su padre
asociación se presenta con una estructura de datos en el sujeto como por
(sujeto).
ejemplo una lista, array, etc. Sin embargo, si se está actuando en un
o Tras ser informado de un cambio en el sujeto concreto, un observador
concreto interroga al sujeto para modificar la percepción que tiene de
escenario en el cual en la mayoría de los casos los sujetos no tienen
observadores esto produce una penalización por uso de una estructura
que no se está empleando en cuanto a espacio se refiere. Para evitar esta
dicho sujeto.
-85-
-86-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
penalización se propone un objeto intermedio que sea el que tenga en
cuando se recibe una actualización se desconoce que sujeto la ha
cuenta la asociación aunque esto implique un mayor coste en el acceso a
provocado.
los observadores. En el caso de emplear un intermediario el sujeto no
La postura clásica es recuperar el estado de todos los
tiene la responsabilidad de actualizar a todos los observadores sino que
sujetos que se tienen asociados.
delega esta tarea en el gestor de observadores. Además si el gestor de
Otra alternativa es indicar el sujeto que ha provocado la
observadores fuese único se podría emplear un patrón instancia única.
actualización, para ello se puede pasar el sujeto como
parámetro del método actualizar. De este modo se puede
Sujeto
Modificar()
AñadirObservador(o)
Gestor de Observadores
Actualizar(sujeto)
*
Observador
Actualizar()
recuperar selectivamente la inforamción.
o Responsabilidad de inicio de la notificación:
Sujeto invoca la notificación tras ejecutarse un método que
cambie su estado.
Nótese que en caso de emplear un gestor de observadores debe existir un
Clientes del sujeto (posiblemente los propios observadores u
método que a cada sujeto le permite actualizar los observadores que tiene
otros) son responsables de comenzar la notificación de
asociados. Además se debe señalar que se ahorra espacio en el Sujeto,
actualización cuando provoquen un cambio en el sujeto. Esto
haciéndolo más ligero pero se penaliza en tiempo de ejecución puesto
suele suponer una complicación adicional en el cliente que, en
que de este modo existen dos niveles de indirección en lugar de uno solo.
general, se debe evitar.
o Observación de más de un sujeto. En algunos casos los observadores
o Referencias inválidas tras borrar un sujeto. En los lenguajes donde es
dependen del estado de más de un sujeto (de igual o de distinto tipo). En
necesario hacer explícita la gestión de memoria, como por ejemplo C++,
este caso es necesario cambiar la cardinalidad de la relación sujeto o
si produce un borrado de un sujeto concreto sin considerar los
tener varias relaciones sujeto.
observadores que tiene asociados puede provocar comportamientos
inesperados. Para evitar problemas antes de borrar un sujeto se debería
hacer una notificación especial a todos sus observadores.
Nótese también que antes de proceder al borrado de un observador se
debería eliminar este de la asociación de observadores del sujeto.
o Asegurar la consistencia del estado del sujeto antes de iniciar la
notificación. Es importante asegurarnos de que la notificación se lleve a
cabo cuando la transacción que implica el cambio en el sujeto se ha
finalizado. (Ver patrón plantilla).
o Evitar actualización dependiente del observador:
Desde el punto de vista del funcionamiento del sujeto se funciona del
mismo modo pero no desde el punto de vista del observador puesto que
-87-
El sujeto notifica los cambios y los observadores piden
información necesaria para ver si se tienen que actualizar o no. Es
lo que se denomina pull model. Este modelo es ineficiente en
-88-
Patrones de diseño
Máster en Bases de Datos e Internet
Máster en Bases de Datos e Internet
cuanto a que obliga a preguntar a los observadores aunque el
Problema: Puede necesitarse más de una forma de recorrer la
cambio no les vaya a afectar pero reduce el acomplamiento entre
estructura: se complica la interfaz de la clase. Por ejemplo, con
jerarquías.
las listas tienes que añadir recorrer hacia atrás.
El sujeto envía información detallada sobre el cambio que ha
Problema: Si se necesita un recorrido no previsto es necesario
realizado, de este modo sólo los observadores a los que le afecta
modificar la clase, que ya está funcionando o implementarlo en
el cambio se actualizarán. Es lo que se denomina push model.
las clases que usan esa nueva funcionalidad lo cual no es
Este modelo es más eficiente pero menos reusable.
reutilizable.
o Especificación explícita de las modificaciones (push model).
•
Patrones de diseño
Solución: Mover la responsabilidad del recorrido a un objeto
iterador. Serparar la estructura de datos en dos partes, la que
Código ejemplo:
o Ejercicio 1: Analiza las clases del ejemplo proporcionado y elabora un
diagrama de clases y de secuencia.
contiene los propios datos y la que sabe en que posición nos
encontramos y como navegar a través de ella.
o Ejercicio 2: Observa que en el código de los diferentes observadores
concretos existen partes comunes que se pueden factorizar. Factoriza las
actuaciones comunes para evitar replicar código.
o Ejercicio3: Con la nueva implementación realiza un diagrama de
secuencia.
o Ejercicio 4: Java proporciona una implementación del patrón
observador. Analizar la documentación proporcionada en el javadoc de
las clases Observable y Observer del paquete java.util.
No tiene por qué limitarse a recorrer la estructura (por ejemplo,
filtrado).
Patrón Iterator o Iterador
•
Clasificación: De comportamiento porque determina como se debe realizar el
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
•
Problema: Los clientes de la estructura de datos deben conocer la
estructura concreta para crear un iterador.
Propósito: Mecanismo de acceso a los elementos que constituyen una estructura
Solución: Generalizar los distintos iteradores en una superclase y
de datos sin exponer su representación interna; es decir, conocer los detalles
dotar a las estructuras de datos de un método de fabricación que
internos de la estructura.
cree un iterador concreto.
Motivación:
o Se desea acceder a los elementos de un contenedor de objetos (por
ejemplo, una lista enlazada) sin exponer su representación interna:
Solución: Añadir métodos que permitan recorrer la estructura sin
referenciar explícitamente su representación. Por ejemplo con un
vector, añadir elemento, acceder a la posición i-ésima.
-89-
-90-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Iterador
Máster en Bases de Datos e Internet
Concreto
(ConcreteIterator):
Implementa
la
interfaz
propuesta por el Iterador. Mantiene la posición actual en el recorrido de
la estructura.
o Agregado (Aggregate): Define la interfaz para el método de fabricación
de iteradores, es decir, para la creación de un objeto iterador de la otra
jerarquía.
o Agregado Concreto (ConcreteAggregate): Implementa la estructura de
datos. Implementa el método de fabricación de iteradotes que crea un
iterador específico para su estructura.
•
Colaboraciones entre participantes: Un iterador concreto mantiene la posición
actual dentro de la estructura de datos e interactúa con ésta para calcular el
•
siguiente elemento en el recorrido.
Aplicabilidad:
o Acceso al contenido de una estructura sin exponer su representación
•
interna.
•
Consecuencias:
o Distintos tipos de recorrido.
o Distintos tipos de recorrido sobre la estructura.
o Simplificación de la interfaz del agregado.
o Interfaz uniforme para recorrer diferentes tipos de estructuras.
o Más de un recorrido simultáneo.
•
Estructura:
Implementación:
o Control de la iteración: iterador externo vs. iterador interno.
o Definición del recorrido.
o Robustez del iterador ante cambios en la estructura.
o Operaciones adicionales en el iterador.
o Iteradores pueden necesitar acceso privilegiado.
o Iteradores para Composición.
o Iteradores nulos.
Patrón Template Method o Plantilla
•
•
Clasificación: De comportamiento porque determina como se debe realizar el
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
Participantes:
o Iterador (Iterator): Define la interfaz para recorrer y acceder al
agregado de elementos.
•
Propósito: Define el esqueleto de un algoritmo en una operación, pero difiere
algunos pasos a las subclases, debido a que existen partes del algoritmo que
dependen de la especialización. Estas partes se implementarán en las subclases.
-91-
-92-
Patrones de diseño
•
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o Para controlar la extensiones de las subclases. El método plantilla utiliza
Motivación:
métodos especiales (hooks) que son los únicos puntos que pueden ser
o Framework para aplicaciones que permiten presentar múltiples
redefinidos en las subclases. Los métodos esqueleto no se deben redefinir
documentos al usuario (abstracciones Aplicación y Documento).
en las subclases por ello en Java se indican como métodos finales (final).
o Para una aplicación específica, se especializan los conceptos de
Aplicación y Documento.
•
Estructura:
•
Participantes:
o Problema: La abstracción aplicación conoce la operación genérica a
realizar (por ejemplo, abrir un documento), pero parte de la operación
depende del documento concreto.
o Solución: Implementar un método que difiera en otros métodos
abstractos las partes del algoritmo que no se conocen o que son
específicas.
o Clase Abstracta (AbstractClass): Define operaciones primitivas
(normalmente abstractas) que las subclases implementan. Implementa un
método plantilla que define el esqueleto de un algoritmo y que utiliza las
operaciones primitivas.
o Clase
o Un método plantilla es un método que define un algoritmo en base a una
•
permitir que las subclases definan el comportamiento que cambia (visión
top-down).
operaciones
Colaboraciones entre participantes: Las clases concretas confían en la clase
parte variable es responsabilidad de cada una de las subclases.
•
o Implementar las partes invariables de un algoritmo una única vez y
las
abstracta la responsabilidad de la parte invariable del algoritmo, mientras que la
funcionamiento no se conoce a nivel de las clases genéricas.
Aplicabilidad:
Implementa
las subclases.
genéricas comunes a todas las subclases en las que parte de su
•
(ConcreteClass):
primitivas que definen el comportamiento específico del algoritmo para
serie de operaciones abstractas que son redefinidas por las. Subclases
para obtener un comportamiento concreto. Es decir, hay operaciones
Concreta
Consecuencias:
o Fundamental para la reutilización de código, puesto que evita la
repetición del código genérico facilitando el posterior mantenimiento de
este.
o Factorización de comportamiento común de las subclases en la
superclase, evitando la replicación de código mediante generalización
o Invierte el control: la superclase es la encargada de llamar a las
operaciones definidas en las subclases.
(visión botton-up).
-93-
-94-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Distinción entre:
Máster en Bases de Datos e Internet
o Problema: Difícil de entender, mantener, modificar y extender puesto
Operación primitiva definida en la superclase normalmente como
que cada clase (variable, asignación,...) tiene su parte correspondiente de
abstracta para obligar a cada una de las subclases a
cada una de las operaciones.
implementarla.
o Solución: Agrupar las operaciones relacionadas de cada clase en un
Operaciones de enganche (Hooks) proporcionan código por
objeto (visitante) y pasarlo como argumento a los elementos del árbol
defecto en la superclase (quizá el comportamiento por defecto, el
sintáctico. El elemento “acepta” al visitante enviándole una petición
cual puede ser no hacer nada) que puede ser refinado en las
específica para su clase con él mismo como argumento:
subclases si es necesario.
VariableRef → VisitVariableRef
Assignment → VisitAssignment
Patrón Visitor o Visitante
•
Clasificación: De comportamiento porque determina como se debe realizar el
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
Propósito: Permite definir una operación sobre objetos de una jerarquía de
clases sin modificar las clases sobre las que opera.
•
Motivación:
o Compilador que representa programas como árboles con su sintaxis
abstracta.
o Necesarias diversas operaciones sobre el árbol sintáctico: Comprobación
de tipos, optimización de código, reestructuración de código, generación
o Para permitir más de un visitante, se define una superclase abstracta con
de código, instrumentación...
una operación por cada tipo de nodo (dos jerarquías!).
o Cada nodo en el árbol sintáctico necesita un tratamiento diferente: clases.
•
Aplicabilidad:
o Varias clases de objetos con interfaces diferentes y se desean realizar
operaciones que dependen de sus clases concretas.
-95-
-96-
Patrones de diseño
Máster en Bases de Datos e Internet
o Se necesitan diversas operaciones (no siempre relacionadas) sobre
Patrones de diseño
•
objetos de una jerarquía y no se desea recargar las clases con estas
Máster en Bases de Datos e Internet
Colaboraciones entre participantes:
o El cliente debe crear un visitante concreto y luego visitar cada elemento
operaciones:
de la estructura de objetos con dicho visitante.
Agrupa operaciones relacionadas en una clase.
o Cuando se visita un elemento, éste llama a la operación del visitante
Si la jerarquía se usa en diversas aplicaciones, sólo se incluyen
correspondiente a su clase.
las operaciones relevantes.
o Normalmente, el objeto se pasa como argumento para permitir al
o Las clases de la jerarquía no cambian, pero se añaden con frecuencia
visitante el acceso a su estado.
operaciones a la estructura. Si la jerarquía cambia, NO es aplicable.
•
Estructura:
•
Consecuencias:
o Añadir operaciones nuevas es sencillo.
o Agrupa operaciones relacionadas y separa las no relacionadas.
o Difícil añadir nuevas clases de elementos.
o No tiene que limitarse a una única jerarquía de elementos.
o Facilita la acumulación de estado.
•
o Problemas con la encapsulación.
Participantes:
o Visitante (Visitor): Declara una operación de visita para cada elemento
concreto en la estructura de objetos, que incluye el propio objeto
Patrón Command o Comando
•
visitado.
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
o Visitante Concreto (ConcreteVisitor): Implementa las operaciones del
visitante y acumula resultados como estado local.
Clasificación: De comportamiento porque determina como se debe realizar el
•
Propósito: Encapsula una petición como un objeto. Permite la parametrizaci´on
de clientes con diferentes peticiones, crear colas de peticiones y soporte de
o Elemento (Element): Define una operación “Accept” que toma un
operaciones cancelables (undo).
visitante como argumento.
o Elemento Concreto (ConcreteElement): Implementa la operación
“Accept”.
•
Motivación:
o En ocasiones es necesario realizar peticiones sin:
-97-
-98-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
Conocer información acerca de la operación a realizar.
Conocer información acerca del receptor de la petición.
o Ejemplo: Herramientas para la creación de interfaces de usuario:
Botones y opciones de menú ejecutan una petición, pero esa
petición depende de la aplicación.
o Solución: Convertir la petición en un objeto.
o Clave: Clase abstracta que declara la interfaz para la ejecución de
operaciones.
o Macrocomando: composición de comandos:
o Las subclases concretas de Command especifican el par receptor-acción:
Atributo que almacena referencia al receptor.
Comportamiento de la clase define la acción.
o Fundamental: Separación del objeto que desencadena la operación del
o Comando Pegar:
objeto que conoce como llevarla a cabo:
Compartición de comandos por diferentes elementos.
Cambio dinámico de comandos (sensible al contexto)
Composición de comandos (scripting)
•
Aplicabilidad:
o Establecer como parámetro de un objeto la acción a realizar (visión OO
de un callback)
o Comando Abrir:
o Especificar, encolar, y ejecutar peticiones en diferentes momentos
o Soporte de Deshacer
El comando almacena estado para invertir su efecto
Añadir método Unexecute a la interfaz del comando
Comandos ejecutados se guardan en una lista histórica
-99-
-100-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Undo-Redo → recorrer la lista adelante y atrás llamando a
Máster en Bases de Datos e Internet
o El Comando Concreto invoca las operaciones sobre el receptor para
Unexecute y Execute respectivamente
realizar la petición.
o Soporte de Logging
Aumentando la interfaz del comando con operaciones de salvarguardar (log persistente de cambios)
Recuperación: cargar los comandos guardados e invocar su
Execute en secuencia
o Soporte de Transacciones
•
Estructura:
•
Consecuencias:
o Desacoplamiento del objeto que invoca la operación del objeto que
conoce como llevarla a cabo.
o Comandos pueden ser manipulados y extendidos como cualquier objeto.
o Composición de comandos.
o Fácil añadir comandos: no es necesario modificar clases existentes.
•
•
o Responsabilidad asignada al comando.
Participantes:
o Soporte de Undo/Redo.
o Comando (Command): Declara la interfaz para ejecutar una operación.
o Evitar acumulación de errores en el proceso de deshacer.
o Comando Concreto (ConcreteCommand): Define un vínculo entre un
objeto receptor y una acción. Implementa la interfaz Comando,
invocando la operación sobre el receptor
o Cliente (Client): Crea un Comando Concreto y establece su receptor
o Invocador (Invoker): Solicita al comando que ejecute su acción
o Receptor (Receiver): Conoce cómo realizar las operaciones asociadas
con la ejecución de un comando
•
Implementación:
Colaboraciones entre participantes:
o Cliente crea Comando Concreto y especifica su receptor.
o El invocador envía el mensaje Execute a un comando.
o El Comando Concreto almacena el estado necesario para deshacer.
-101-
Patrón Memento o Recuerdo
•
Clasificación: De comportamiento porque determina como se debe realizar el
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
Propósito: Permite capturar y extraer el estado interno de un objeto, sin violar
su encapsulación, de tal modo que se puede restaurar su estado a posteriori.
•
Motivación: Operaciones de deshacer, transacciones...
•
Aplicabilidad:
o Cuando se dan las dos siguientes condiciones:
Una imagen del estado del objeto (o un subconjunto) debe ser
almacenado de tal forma que pueda ser restaurado más tarde.
-102-
Patrones de diseño
Máster en Bases de Datos e Internet
Una interfaz directa para obtener el estado expondría detalles de
Patrones de diseño
•
implementación, violando la encapsulación del objeto.
•
Máster en Bases de Datos e Internet
Consecuencias:
o Evita la exposición de información que sólo debe gestionar el originante,
pero que debe guardarse fuera de éste.
Estructura:
o Simplifica el originante, al separar la gestión de los recuerdos.
o Puede resultar costoso.
o Difícil en algunos lenguajes el soporte de dos visibilidades distintas.
o Oculta el coste de almacenamiento del recuerdo.
•
Implementación:
o Soporte de dos visibilidades diferentes
•
Participantes:
o Almacenamiento de cambios incrementales
o Recuerdo (Memento): Almacena el estado interno de la clase
Particularmente útil en la implementación de operación deshacer
Originante. Sólo permite el acceso al estado almacenado a la clase
dado que se conoce la secuencia de cambios realizados (histórico)
Originante.
o Originante (Originator): Crea un Recuerdo con la imagen de su estado
actual. Usa un Recuerdo para restaurar su estado interno.
Patrón Mediator o Mediador
•
o Cuidador (Caretaker): Responsable de almacenar los Recuerdos. No
opera o examina el contenido de los Recuerdos.
•
intercambio de mensajes entre los diferentes objetos para resolver una tarea.
•
Colaboraciones entre participantes:
o El cuidador solicita un recuerdo del originante, lo almacena por un
tiempo, y si es necesario, lo devuelve al originante
Clasificación: De comportamiento porque determina como se debe realizar el
Propósito: Define un objeto que encapsula la interacción entre varios objetos
independientes.
•
Motivación:
o OO distribuye comportamiento/responsabilidad entre objetos:
Estructura de objetos con múltiples conexiones
Caso extremo: objetos totalmente conexos
o Consecuencia: pérdida de independencia reduce reusabilidad:
El sistema actúa de forma monolítica: para reusar un componente
se necesitan aquellos de los que depende
Difícil cambiar el comportamiento al estar repartido entre
muchos objetos
o Ejemplo: Ventanas de diálogo
o Los recuerdos son pasivos
-103-
-104-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
o Existen dependencias entre los componentes:
Selecciones realizadas sobre unos componentes pueden modificar
el estado de otros componentes.
o Diferentes
diálogos
tienen
diferentes
dependencias
entre
los
o El coordinador media entre la lista de selección y el campo de edición:
componentes:
Lista de selección cambio al mediador.
Necesario extender clases existentes para implementar el
Mediador consultaba el valor actual de la lista.
comportamiento específico (tedioso, no reutilizable)
Mediador solicita al campo de edición que cambie.
o Solución: Encapsular el comportamiento colectivo en un objeto
mediador:
Responsable de controlar y coordinar la interacción.
Intermediario que evita el conocimiento directo entre los objetos
(los objetos sólo conocen al coordinador)
•
-105-
Aplicabilidad:
-106-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
o Un conjunto de objetos se comunican de manera compleja, siendo sus
mediador en lugar de hacerlo directamente con los restantes objetos
interdependencias difíciles de entender.
coordinados.
o Es difícil reusar un objeto porque hace referencia y se comunica con
•
otros objetos.
Colaboraciones entre participantes:
o Sólo hay comunicación coordinado – mediador.
o El comportamiento de un conjunto de objetos debe ser personalizable sin
o El mediador implementa la coordinación redirigiendo los mensajes a los
necesidad de extender muchas clases.
•
Máster en Bases de Datos e Internet
objetos apropiados.
Estructura:
•
Consecuencias:
o Reduce las extensiones de clases existentes.
o Desacopla objetos coordinados.
o Simplifica protocolo entre objetos.
o Abstrae la forma de cooperación de los objetos.
o Centraliza el control.
•
Implementación:
o Omisión de la clase abstracta Mediador.
o Comunicación medidor – objetos coordinados:
Patrón Observador.
Interfaz de notificación específico.
o Soporte de Observadores complejos.
•
Participantes:
o Mediador (Mediator): Define la interfaz para la comunicaci´on con los
objetos coordinados.
o Mediador
Concreto
(ConcreteMediator):
Implementa
el
comportamiento cooperativo. Conoce y mantiene a los objetos
coordinados.
o Clases coordinadas (Colleague classes): Cada clase coordinada conoce
a su mediador. Un objeto de la clase coordinada se comunica con su
-107-
-108-
Patrones de diseño
Máster en Bases de Datos e Internet
Patrones de diseño
Máster en Bases de Datos e Internet
BIBLIOGRAFÍA Y REFERENCIAS
E. Gamma, R. Helm, R. Johnson, J. Vlissides. Design Patterns. Elements of Reusable
Object-Oriented Software. Addison-Wesley Professional Computing Series, 1995.
ISBN: 0-201-63361-2.
Sitio Web del libro anterior http://hillside.net/patterns/DPBook/DPBook.html [Ultimo
acceso 10 de febrero de 2010].
Larman, Craig. UML y patrones. Segunda Edición. Prentice Hall. 2002.
Sitio Web de Víctor Gulías http://www.fi.udc.es/~gulias [Último acceso 20 de enero de
2009]
M. Fowler, K. Scott. UML Distilled. Addison-Wesley Longman, 1997.
G. Booch, I. Jacobson, J. Rumbaugh. El Lenguaje Unificado de Modelado. Guía del
usuario. Addison-Wesley,1999.
J. Rumbaugh, I. Jacobson, G. Booch, El Lenguaje Unificado de Modelado. Manual de
referencia. Addison-Wesley, 2000.
K. Arnold, J. Gosling. The Java Programming Language. The Java Series, AddisonWesley, 1998.
Herbert Schilt. Java 2. Manual de Referencia. McGraw-Hill, 2001. ISBN: 8448131738.
-109-
-110-
Descargar