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-