Patrones Disenio PDF Free
Patrones Disenio PDF Free
Patrones Disenio PDF Free
PDFelement
Wondershare
PDFelement
Sumér
Sumérggete en lo
loss
PATR
TRONE
ONESS
DE
DI
DISEÑO
SEÑO
v2021-1.7
Índice de contenido
Índice de contenido............................................................................................... 4
Cómo leer este libro.............................................................................................. 6
FUNDAMENTOS DE LA POO .................................................................................. 7
Conceptos básicos de POO ............................................................... 8
Los pilares de la POO ...................................................................... 13
Relaciones entre objetos................................................................ 21
INTRODUCCIÓN A LOS PATRONES DE DISEÑO............................................... 27
¿Qué es un patrón de diseño?...................................................... 28
¿Por qué debería aprender sobre patrones? ........................... 33
PRINCIPIOS DE DISEÑO DE SOFTWARE .......................................................... 34
Características del buen diseño................................................... 35
Principios del diseño..................................................................................... 39
§ Encapsula lo que varía ................................................................ 40
§ Programa a una interfaz, no a una implementación ........ 45
§ Favorece la composición sobre la herencia......................... 50
Principios SOLID ............................................................................................ 54
§ S: Principio de responsabilidad única.................................... 55
§ O: Principio de abierto/cerrado................................................ 57
§ L: Principio de sustitución de Liskov...................................... 61
§ I: Principio de segregación de la interfaz ............................. 68
§ D: Principio de inversión de la dependencia....................... 71
[email protected] (#44357)
Wondershare
5 Índice de contenido PDFelement
#44357
[email protected] (#44357)
Wondershare
6 Cómo leer este libro PDFelement
#44357
Los patrones de diseño son universales. Por ello, todos los eje-
mplos de código de este libro están escritos en un pseudocódi-
go que no restringe el material a un lenguaje de programación
particular.
[email protected] (#44357)
Wondershare
PDFelement
#44357
FUNDAMENTOS
DE LA POO
[email protected] (#44357)
Wondershare
8 Fundamentos de la POO / Conceptos básicos de POO PDFelement
#44357
Objetos, clases
¿Te gustan los gatos? Espero que sí, porque voy a intentar
explicar los conceptos de POO utilizando varios ejemplos
con gatos.
[email protected] (#44357)
Wondershare
9 Fundamentos de la POO / Conceptos básicos de POO PDFelement
#44357
[email protected] (#44357)
Wondershare
10 Fundamentos de la POO / Conceptos básicos de POO PDFelement
#44357
Jerarquías de clase
Todo va muy bien mientras hablamos de una sola clase. Natu-
ralmente, un programa real contiene más de una clase. Algu-
nas de esas clases pueden estar organizadas en jerarquías de
clase. Veamos lo que esto significa.
[email protected] (#44357)
Wondershare
11 Fundamentos de la POO / Conceptos básicos de POO PDFelement
#44357
[email protected] (#44357)
Wondershare
12 Fundamentos de la POO / Conceptos básicos de POO PDFelement
#44357
[email protected] (#44357)
Wondershare
13 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
Abstracción
La mayoría de las veces, cuando creas un programa con POO,
das forma a los objetos del programa con base a objetos del
mundo real. Sin embargo, los objetos del programa no repre-
sentan a los originales con una precisión del 100 % (y rara vez
es necesario que lo hagan). En su lugar, tus objetos tan solo co-
pian atributos y comportamientos de objetos reales en un co-
ntexto específico, ignorando el resto.
[email protected] (#44357)
Wondershare
14 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
Encapsulación
Para arrancar el motor de un auto, tan solo debes girar una
llave o pulsar un botón. No necesitas conectar cables bajo el
capó, rotar el cigüeñal y los cilindros, e iniciar el ciclo de po-
[email protected] (#44357)
Wondershare
15 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
[email protected] (#44357)
Wondershare
16 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
[email protected] (#44357)
Wondershare
17 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
Herencia
La herencia es la capacidad de crear nuevas clases sobre otras
existentes. La principal ventaja de la herencia es la reutiliza-
ción de código. Si quieres crear una clase ligeramente diferen-
te a una ya existente, no hay necesidad de duplicar el código.
En su lugar, extiendes la clase existente y colocas la funciona-
lidad adicional dentro de una subclase resultante que hereda
los campos y métodos de la superclase.
[email protected] (#44357)
Wondershare
18 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
Polimorfismo
Veamos algunos ejemplos con animales. La mayoría de los
Animal puede emitir sonidos. Podemos anticipar que todas
[email protected] (#44357)
Wondershare
19 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
[email protected] (#44357)
Wondershare
20 Fundamentos de la POO / Los pilares de la POO PDFelement
#44357
1 bag = [new
new Cat(), new Dog()];
2
3 foreach (Animal a : bag)
4 a.makeSound()
5
6 // ¡Miau!
7 // ¡Guau!
[email protected] (#44357)
Wondershare
21 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
Dependencia
[email protected] (#44357)
Wondershare
22 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
Asociación
[email protected] (#44357)
Wondershare
23 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
1 class Professor is
2 field Student student
3 // ...
4 method teach(Course c) is
5 // ...
6 this
this.student.remember(c.getKnowledge())
asociación.
[email protected] (#44357)
Wondershare
24 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
Agregación
[email protected] (#44357)
Wondershare
25 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
Composición
La visión global
Ahora que conocemos todos los tipos de relaciones entre ob-
jetos, veamos cómo se conectan entre sí. Esperemos que esto
te ayude a responder preguntas como: “¿cuál es la diferencia
entre agregación y composición?” o “¿la herencia es un tipo de
dependencia?”.
[email protected] (#44357)
Wondershare
26 Fundamentos de la POO / Relaciones entre objetos PDFelement
#44357
[email protected] (#44357)
Wondershare
PDFelement
#44357
INTRODUCCIÓN
A LOS PATRONES
[email protected] (#44357)
Wondershare
28 Introducción a los patrones de diseño / ¿Qué es un patrón de diseño? PDFelement
#44357
[email protected] (#44357)
Wondershare
29 Introducción a los patrones de diseño / ¿Qué es un patrón de diseño? PDFelement
#44357
[email protected] (#44357)
Wondershare
30 Introducción a los patrones de diseño / ¿Qué es un patrón de diseño? PDFelement
#44357
Los patrones más universales y de más alto nivel son los pat-
rones de arquitectura. Los desarrolladores pueden implementar
estos patrones prácticamente en cualquier lenguaje. Al contra-
rio que otros patrones, pueden utilizarse para diseñar la arqui-
tectura de una aplicación completa.
[email protected] (#44357)
Wondershare
31 Introducción a los patrones de diseño / ¿Qué es un patrón de diseño? PDFelement
#44357
[email protected] (#44357)
Wondershare
32 Introducción a los patrones de diseño / ¿Qué es un patrón de diseño? PDFelement
#44357
[email protected] (#44357)
Wondershare
33 PDFelement
#44357
Introducción a los patrones de diseño / ¿Por qué debería aprender sobre patrones?
[email protected] (#44357)
Wondershare
PDFelement
#44357
PRINCIPIOS
DE DISEÑO
DE SOFTWARE
[email protected] (#44357)
Wondershare
35 Principios de diseño de software / Características del buen diseño PDFelement
#44357
Reutilización de código
Costos y tiempo son dos de los parámetros más valiosos a la
hora de desarrollar cualquier producto de software. Dedicar
menos tiempo al desarrollo se traduce en entrar en el mercado
antes que la competencia. Unos costos más bajos en el desar-
rollo significa que habrá más dinero disponible para marketing
y un alcance más amplio a clientes potenciales.
[email protected] (#44357)
Wondershare
36 Principios de diseño de software / Reutilización de código PDFelement
#44357
1
Aquí tienes un apunte de sabiduría de Erich Gamma , uno
de los padres fundadores de los patrones de diseño, sobre el
papel que estos juegan en la reutilización de código:
[email protected] (#44357)
Wondershare
37 Principios de diseño de software / Extensibilidad PDFelement
#44357
„
zar ideas y conceptos de diseño con independencia del código
concreto.
Extensibilidad
El cambio es lo único constante en la vida de un programador.
[email protected] (#44357)
Wondershare
38 Principios de diseño de software / Extensibilidad PDFelement
#44357
[email protected] (#44357)
Wondershare
39 Principios del diseño PDFelement
#44357
[email protected] (#44357)
Wondershare
40 Principios del diseño / Encapsula lo que varía PDFelement
#44357
Del mismo modo, puedes aislar las partes del programa que
varían, en módulos independientes, protegiendo el resto del
código frente a efectos adversos. Al hacerlo, dedicarás menos
tiempo a lograr que el programa vuelva a funcionar, impleme-
ntando y probando los cambios. Cuanto menos tiempo dedi-
ques a realizar cambios, más tiempo tendrás para implementar
funciones.
[email protected] (#44357)
Wondershare
41 Principios del diseño / Encapsula lo que varía PDFelement
#44357
puestos incluidos.
1 method getOrderTotal(order) is
2 total = 0
3 foreach item in order.lineItems
4 total += item.price * item.quantity
5
6 if (order.country == "US")
7 total += total * 0.07 // Impuesto sobre la venta de EUA
8 else if (order.country == "EU"):
9 total += total * 0.20 // IVA europeo
10
11 return total
ANTES: el código de cálculo del impuesto está mezclado con el resto del
código del método.
[email protected] (#44357)
Wondershare
42 Principios del diseño / Encapsula lo que varía PDFelement
#44357
1 method getOrderTotal(order) is
2 total = 0
3 foreach item in order.lineItems
4 total += item.price * item.quantity
5
6 total += total * getTaxRate(order.country)
7
8 return total
9
10 method getTaxRate(country) is
11 if (country == "US")
12 return 0.07 // Impuesto sobre la venta de EUA
13 else if (country == "EU")
14 return 0.20 // IVA europeo
15 else
16 return 0
[email protected] (#44357)
Wondershare
43 Principios del diseño / Encapsula lo que varía PDFelement
#44357
[email protected] (#44357)
Wondershare
44 Principios del diseño / Encapsula lo que varía PDFelement
#44357
[email protected] (#44357)
Wondershare
45 PDFelement
Principios del diseño / Programa a una interfaz, no a una implementación #44357
[email protected] (#44357)
Wondershare
46 PDFelement
Principios del diseño / Programa a una interfaz, no a una implementación #44357
[email protected] (#44357)
Wondershare
47 PDFelement
Principios del diseño / Programa a una interfaz, no a una implementación #44357
Ejemplo
Veamos otro ejemplo que ilustra que trabajar con objetos a
través de interfaces puede ser más beneficioso que depender
de sus clases concretas. Imagina que estás creando un simu-
lador de empresa de desarrollo de software. Tienes distintas
clases que representan varios tipos de empleados.
[email protected] (#44357)
Wondershare
48 PDFelement
Principios del diseño / Programa a una interfaz, no a una implementación #44357
[email protected] (#44357)
Wondershare
49 PDFelement
Principios del diseño / Programa a una interfaz, no a una implementación #44357
[email protected] (#44357)
Wondershare
50 Principios del diseño / Favorece la composición sobre la herencia PDFelement
#44357
[email protected] (#44357)
Wondershare
51 Principios del diseño / Favorece la composición sobre la herencia PDFelement
#44357
[email protected] (#44357)
Wondershare
52 Principios del diseño / Favorece la composición sobre la herencia PDFelement
#44357
Ejemplo
Imagina que debes crear una aplicación de un catálogo para
un fabricante de automóviles. La empresa fabrica autos y ca-
miones; pueden ser eléctricos o de gasolina; todos los mode-
los pueden tener controles manuales o piloto automático.
[email protected] (#44357)
Wondershare
53 Principios del diseño / Favorece la composición sobre la herencia PDFelement
#44357
[email protected] (#44357)
Wondershare
54 Principios SOLID PDFelement
#44357
Principios SOLID
Ahora que conoces los principios básicos de diseño, veamos
cinco que se conocen popularmente como los principios
SOLID. Robert Martin los presentó en el libro Desarrollo ágil de
1
software: principios, patrones y prácticas .
[email protected] (#44357)
Wondershare
55 Principios SOLID / S: Principio de responsabilidad única PDFelement
#44357
Hay más: si una clase hace demasiadas cosas, tienes que cambiarla
cada vez que una de esas cosas cambia. Al hacerlo, te arriesgas a
descomponer otras partes de la clase que no pretendías cambiar. Si
sientes que te resulta difícil centrarte en un aspecto específico del
programa cada vez, recuerda el principio de responsabilidad única
y comprueba si es el momento de dividir algunas clases en partes.
[email protected] (#44357)
Wondershare
56 Principios SOLID / S: Principio de responsabilidad única PDFelement
#44357
Ejemplo
La clase Empleado tiene varias razones para cambiar. La pri-
mera razón puede estar relacionada con el trabajo principal
de la clase: gestionar información de los empleados. Pero hay
otra razón: el formato del informe de horas de trabajo puede
cambiar con el tiempo, lo que te obliga a cambiar el código de
la clase.
[email protected] (#44357)
Wondershare
57 Principios SOLID / O: Principio de abierto/cerrado PDFelement
#44357
O pen/Closed Principle
Principio de abierto/cerrado
[email protected] (#44357)
Wondershare
58 Principios SOLID / O: Principio de abierto/cerrado PDFelement
#44357
Ejemplo
Tienes una aplicación de comercio electrónico con una clase
Pedido que calcula los costos de envío, y todos los métodos
[email protected] (#44357)
Wondershare
59 Principios SOLID / O: Principio de abierto/cerrado PDFelement
#44357
[email protected] (#44357)
Wondershare
60 Principios SOLID / O: Principio de abierto/cerrado PDFelement
#44357
[email protected] (#44357)
Wondershare
61 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
[email protected] (#44357)
Wondershare
62 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
◦ Digamos que hay una clase con un método que debe alime-
ntar gatos: alimentar(Gato c) . El código cliente siempre
pasa objetos de gatos a este método.
[email protected] (#44357)
Wondershare
63 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
◦ Digamos que
tienes una clase con el método
comprarGato(): Gato . El código cliente espera recibir cua-
[email protected] (#44357)
Wondershare
64 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
[email protected] (#44357)
Wondershare
65 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
[email protected] (#44357)
Wondershare
66 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
Ejemplo
Veamos un ejemplo de una jerarquía de clases de documento
que violan el principio de sustitución.
[email protected] (#44357)
Wondershare
67 Principios SOLID / L: Principio de sustitución de Liskov PDFelement
#44357
[email protected] (#44357)
Wondershare
68 Principios SOLID / I: Principio de segregación de la interfaz PDFelement
#44357
[email protected] (#44357)
Wondershare
69 Principios SOLID / I: Principio de segregación de la interfaz PDFelement
#44357
Ejemplo
Imagina que creaste una biblioteca que facilita la integración de
aplicaciones con varios proveedores de computación en la nube.
Aunque en la versión inicial sólo soportaba Amazon Cloud, cubría
todos los servicios y funciones de la nube.
[email protected] (#44357)
Wondershare
70 Principios SOLID / I: Principio de segregación de la interfaz PDFelement
#44357
[email protected] (#44357)
Wondershare
71 Principios SOLID / D: Principio de inversión de la dependencia PDFelement
#44357
[email protected] (#44357)
Wondershare
72 Principios SOLID / D: Principio de inversión de la dependencia PDFelement
#44357
3. Una vez que las clases de bajo nivel implementan esas interfa-
ces, se vuelven dependientes del nivel de la lógica de negocio,
invirtiendo la dirección de la dependencia original.
Ejemplo
En este ejemplo, la clase de alto nivel — que se ocupa de in-
formes presupuestarios — utiliza una clase de base de datos
de bajo nivel para leer y almacenar su información. Esto si-
gnifica que cualquier cambio en la clase de bajo nivel, como
en el caso del lanzamiento de una nueva versión del servi-
[email protected] (#44357)
Wondershare
73 Principios SOLID / D: Principio de inversión de la dependencia PDFelement
#44357
ANTES: una clase de alto nivel depende de una clase de bajo nivel.
[email protected] (#44357)
Wondershare
74 Principios SOLID / D: Principio de inversión de la dependencia PDFelement
#44357
[email protected] (#44357)
Wondershare
PDFelement
#44357
EL CATÁLOGO
DE PATRONES
DE DISEÑO
[email protected] (#44357)
Wondershare
76 Patrones creacionales PDFelement
#44357
Patrones creacionales
Los patrones creacionales proporcionan varios mecanismos de
creación de objetos que incrementan la flexibilidad y la reuti-
lización del código existente.
Factory
Method
Proporciona una interfaz para la creación de objetos en una su-
perclase, mientras permite a las subclases alterar el tipo de obje-
tos que se crearán.
Abstract
Factory
Permite producir familias de objetos relacionados sin especificar
sus clases concretas.
[email protected] (#44357)
Wondershare
77 Patrones creacionales PDFelement
#44357
Builder
Permite construir objetos complejos paso a paso. Este patrón nos
permite producir distintos tipos y representaciones de un objeto
empleando el mismo código de construcción.
Prototype
Permite copiar objetos existentes sin que el código dependa de
sus clases.
Singleton
Permite asegurarnos de que una clase tenga una única instancia,
a la vez que proporciona un punto de acceso global a dicha insta-
ncia.
[email protected] (#44357)
Wondershare
78 Patrones creacionales / Factory Method PDFelement
#44357
FACTORY METHOD
También llamado: Método fábrica, Constructor virtual
[email protected] (#44357)
Wondershare
79 Patrones creacionales / Factory Method PDFelement
#44357
Problema
Imagina que estás creando una aplicación de gestión logística.
La primera versión de tu aplicación sólo es capaz de manejar
el transporte en camión, por lo que la mayor parte de tu códi-
go se encuentra dentro de la clase Camión .
[email protected] (#44357)
Wondershare
80 Patrones creacionales / Factory Method PDFelement
#44357
Solución
El patrón Factory Method sugiere que, en lugar de llamar al
operador new para construir objetos directamente, se invo-
que a un método fábrica especial. No te preocupes: los objetos
se siguen creando a través del operador new , pero se invocan
desde el método fábrica. Los objetos devueltos por el método
fábrica a menudo se denominan productos.
[email protected] (#44357)
Wondershare
81 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
82 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
83 Patrones creacionales / Factory Method PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
84 Patrones creacionales / Factory Method PDFelement
#44357
Pseudocódigo
Este ejemplo ilustra cómo puede utilizarse el patrón Factory
Method para crear elementos de interfaz de usuario (UI) multi-
plataforma sin acoplar el código cliente a clases UI concretas.
[email protected] (#44357)
Wondershare
85 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
86 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
87 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
88 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
89 Patrones creacionales / Factory Method PDFelement
#44357
Aplicabilidad
Utiliza el Método Fábrica cuando no conozcas de antemano las
dependencias y los tipos exactos de los objetos con los que
deba funcionar tu código.
[email protected] (#44357)
Wondershare
90 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
91 Patrones creacionales / Factory Method PDFelement
#44357
Cómo implementarlo
1. Haz que todos los productos sigan la misma interfaz. Esta inte-
rfaz deberá declarar métodos que tengan sentido en todos los
productos.
[email protected] (#44357)
Wondershare
92 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
93 Patrones creacionales / Factory Method PDFelement
#44357
Pros y contras
Evitas un acoplamiento fuerte entre el creador y los productos
concretos.
Principio de responsabilidad única. Puedes mover el código de
creación de producto a un lugar del programa, haciendo que
el código sea más fácil de mantener.
Principio de abierto/cerrado. Puedes incorporar nuevos tipos de
productos en el programa sin descomponer el código cliente
existente.
[email protected] (#44357)
Wondershare
94 Patrones creacionales / Factory Method PDFelement
#44357
[email protected] (#44357)
Wondershare
95 Patrones creacionales / Abstract Factory PDFelement
#44357
ABSTRACT FACTORY
También llamado: Fábrica abstracta
[email protected] (#44357)
Wondershare
96 Patrones creacionales / Abstract Factory PDFelement
#44357
Problema
Imagina que estás creando un simulador de tienda de mueb-
les. Tu código está compuesto por clases que representan lo
siguiente:
[email protected] (#44357)
Wondershare
97 Patrones creacionales / Abstract Factory PDFelement
#44357
Solución
Lo primero que sugiere el patrón Abstract Factory es que de-
claremos de forma explícita interfaces para cada producto di-
ferente de la familia de productos (por ejemplo, silla, sofá o
mesilla). Después podemos hacer que todas las variantes de
los productos sigan esas interfaces. Por ejemplo, todas las va-
riantes de silla pueden implementar la interfaz Silla , así
[email protected] (#44357)
Wondershare
98 Patrones creacionales / Abstract Factory PDFelement
#44357
Todas las variantes del mismo objeto deben moverse a una única jerarquía
de clase.
[email protected] (#44357)
Wondershare
99 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
100 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
101 Patrones creacionales / Abstract Factory PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
102 Patrones creacionales / Abstract Factory PDFelement
#44357
Pseudocódigo
Este ejemplo ilustra cómo puede utilizarse el patrón Abstract
Factory para crear elementos de interfaz de usuario (UI) multi-
plataforma sin acoplar el código cliente a clases UI concretas,
mientras se mantiene la consistencia de todos los elementos
creados respecto al sistema operativo seleccionado.
[email protected] (#44357)
Wondershare
103 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
104 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
105 Patrones creacionales / Abstract Factory PDFelement
#44357
10 method createCheckbox():Checkbox
11
12
13 // Las fábricas concretas producen una familia de productos que
14 // pertenecen a una única variante. La fábrica garantiza que los
15 // productos resultantes sean compatibles. Las firmas de los
16 // métodos de las fábricas concretas devuelven un producto
17 // abstracto mientras que dentro del método se instancia un
18 // producto concreto.
19 class WinFactory implements GUIFactory is
20 method createButton():Button is
21 return new WinButton()
22 method createCheckbox():Checkbox is
23 return new WinCheckbox()
24
25 // Cada fábrica concreta tiene una variante de producto
26 // correspondiente.
27 class MacFactory implements GUIFactory is
28 method createButton():Button is
29 return new MacButton()
30 method createCheckbox():Checkbox is
31 return new MacCheckbox()
32
33
34 // Cada producto individual de una familia de productos debe
35 // tener una interfaz base. Todas las variantes del producto
36 // deben implementar esta interfaz.
37 interface Button is
38 method paint()
39
40 // Los productos concretos son creados por las fábricas
41 // concretas correspondientes.
[email protected] (#44357)
Wondershare
106 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
107 Patrones creacionales / Abstract Factory PDFelement
#44357
74 this
this.factory = factory
75 method createUI() is
76 this
this.button = factory.createButton()
77 method paint() is
78 button.paint()
79
80
81 // La aplicación elige el tipo de fábrica dependiendo de la
82 // configuración actual o de los ajustes del entorno y la crea
83 // durante el tiempo de ejecución (normalmente en la etapa de
84 // inicialización).
85 class ApplicationConfigurator is
86 method main() is
87 config = readApplicationConfigFile()
88
89 if (config.OS == "Windows") then
90 factory = new WinFactory()
91 else if (config.OS == "Mac") then
92 factory = new MacFactory()
93 else
94 throw new Exception("Error! Unknown operating system.")
95
96 Application app = new Application(factory)
Aplicabilidad
Utiliza el patrón Abstract Factory cuando tu código deba fun-
cionar con varias familias de productos relacionados, pero no
desees que dependa de las clases concretas de esos productos,
ya que puede ser que no los conozcas de antemano o sencilla-
mente quieras permitir una futura extensibilidad.
[email protected] (#44357)
Wondershare
108 Patrones creacionales / Abstract Factory PDFelement
#44357
Cómo implementarlo
1. Mapea una matriz de distintos tipos de productos frente a va-
riantes de dichos productos.
[email protected] (#44357)
Wondershare
109 Patrones creacionales / Abstract Factory PDFelement
#44357
Pros y contras
Puedes tener la certeza de que los productos que obtienes de
una fábrica son compatibles entre sí.
Evitas un acoplamiento fuerte entre productos concretos y el
código cliente.
Principio de responsabilidad única. Puedes mover el código de
creación de productos a un solo lugar, haciendo que el código
sea más fácil de mantener.
Principio de abierto/cerrado. Puedes introducir nuevas variantes
de productos sin descomponer el código cliente existente.
[email protected] (#44357)
Wondershare
110 Patrones creacionales / Abstract Factory PDFelement
#44357
[email protected] (#44357)
Wondershare
111 Patrones creacionales / Builder PDFelement
#44357
BUILDER
También llamado: Constructor
[email protected] (#44357)
Wondershare
112 Patrones creacionales / Builder PDFelement
#44357
Problema
Imagina un objeto complejo que requiere una inicialización la-
boriosa, paso a paso, de muchos campos y objetos anidados.
Normalmente, este código de inicialización está sepultado de-
ntro de un monstruoso constructor con una gran cantidad de
parámetros. O, peor aún: disperso por todo el código cliente.
[email protected] (#44357)
Wondershare
113 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
114 Patrones creacionales / Builder PDFelement
#44357
Solución
El patrón Builder sugiere que saques el código de construcción
del objeto de su propia clase y lo coloques dentro de objetos
independientes llamados constructores.
[email protected] (#44357)
Wondershare
115 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
116 Patrones creacionales / Builder PDFelement
#44357
Clase directora
[email protected] (#44357)
Wondershare
117 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
118 Patrones creacionales / Builder PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
119 Patrones creacionales / Builder PDFelement
#44357
Pseudocódigo
Este ejemplo del patrón Builder ilustra cómo se puede reuti-
lizar el mismo código de construcción de objetos a la hora
de construir distintos tipos de productos, como automóviles, y
crear los correspondientes manuales para esos automóviles.
[email protected] (#44357)
Wondershare
120 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
121 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
122 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
123 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
124 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
125 Patrones creacionales / Builder PDFelement
#44357
93 method setEngine(...) is
94 // Añade instrucciones del motor.
95
96 method setTripComputer(...) is
97 // Añade instrucciones de la computadora de navegación.
98
99 method setGPS(...) is
100 // Añade instrucciones del GPS.
101
102 method getProduct():Manual is
103 // Devuelve el manual y rearma el constructor.
104
105
106 // El director sólo es responsable de ejecutar los pasos de
107 // construcción en una secuencia particular. Resulta útil cuando
108 // se crean productos de acuerdo con un orden o configuración
109 // específicos. En sentido estricto, la clase directora es
110 // opcional, ya que el cliente puede controlar directamente los
111 // objetos constructores.
112 class Director is
113 private field builder:Builder
114
115 // El director funciona con cualquier instancia de
116 // constructor que le pase el código cliente. De esta forma,
117 // el código cliente puede alterar el tipo final del
118 // producto recién montado.
119 method setBuilder(builder:Builder)
120 this
this.builder = builder
121
122 // El director puede construir multitud de variaciones de
123 // producto utilizando los mismos pasos de construcción.
124 method constructSportsCar(builder: Builder) is
[email protected] (#44357)
Wondershare
126 Patrones creacionales / Builder PDFelement
#44357
125 builder.reset()
126 builder.setSeats(2)
127 builder.setEngine(new
new SportEngine())
128 builder.setTripComputer(true
true)
129 builder.setGPS(true
true)
130
131 method constructSUV(builder: Builder) is
132 // ...
133
134
135 // El código cliente crea un objeto constructor, lo pasa al
136 // director y después inicia el proceso de construcción. El
137 // resultado final se extrae del objeto constructor.
138 class Application is
139
140 method makeCar() is
141 director = new Director()
142
143 CarBuilder builder = new CarBuilder()
144 director.constructSportsCar(builder)
145 Car car = builder.getProduct()
146
147 CarManualBuilder builder = new CarManualBuilder()
148 director.constructSportsCar(builder)
149
150 // El producto final a menudo se extrae de un objeto
151 // constructor, ya que el director no conoce y no
152 // depende de constructores y productos concretos.
153 Manual manual = builder.getProduct()
[email protected] (#44357)
Wondershare
127 Patrones creacionales / Builder PDFelement
#44357
Aplicabilidad
Utiliza el patrón Builder para evitar un “constructor
telescópico”.
1 class Pizza {
2 Pizza(int size) { ... }
3 Pizza(int size, boolean cheese) { ... }
4 Pizza(int size, boolean cheese, boolean pepperoni) { ... }
5 // ...
[email protected] (#44357)
Wondershare
128 Patrones creacionales / Builder PDFelement
#44357
Cómo implementarlo
1. Asegúrate de poder definir claramente los pasos comunes de
construcción para todas las representaciones disponibles del
producto. De lo contrario, no podrás proceder a implementar
el patrón.
[email protected] (#44357)
Wondershare
129 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
130 Patrones creacionales / Builder PDFelement
#44357
Pros y contras
Puedes construir objetos paso a paso, aplazar pasos de la con-
strucción o ejecutar pasos de forma recursiva.
Puedes reutilizar el mismo código de construcción al construir
varias representaciones de productos.
Principio de responsabilidad única. Puedes aislar un código de
construcción complejo de la lógica de negocio del producto.
[email protected] (#44357)
Wondershare
131 Patrones creacionales / Builder PDFelement
#44357
[email protected] (#44357)
Wondershare
132 Patrones creacionales / Prototype PDFelement
#44357
PROTOTYPE
También llamado: Prototipo, Clon, Clone
[email protected] (#44357)
Wondershare
133 Patrones creacionales / Prototype PDFelement
#44357
Problema
Digamos que tienes un objeto y quieres crear una copia exa-
cta de él. ¿Cómo lo harías? En primer lugar, debes crear un
nuevo objeto de la misma clase. Después debes recorrer todos
los campos del objeto original y copiar sus valores en el nuevo
objeto.
Hay otro problema con el enfoque directo. Dado que debes co-
nocer la clase del objeto para crear un duplicado, el código
se vuelve dependiente de esa clase. Si esta dependencia adi-
cional no te da miedo, todavía hay otra trampa. En ocasiones
tan solo conocemos la interfaz que sigue el objeto, pero no su
[email protected] (#44357)
Wondershare
134 Patrones creacionales / Prototype PDFelement
#44357
Solución
El patrón Prototype delega el proceso de clonación a los pro-
pios objetos que están siendo clonados. El patrón declara una
interfaz común para todos los objetos que soportan la clona-
ción. Esta interfaz nos permite clonar un objeto sin acoplar el
código a la clase de ese objeto. Normalmente, dicha interfaz
contiene un único método clonar .
[email protected] (#44357)
Wondershare
135 Patrones creacionales / Prototype PDFelement
#44357
[email protected] (#44357)
Wondershare
136 Patrones creacionales / Prototype PDFelement
#44357
[email protected] (#44357)
Wondershare
137 Patrones creacionales / Prototype PDFelement
#44357
Estructura
Implementación básica
[email protected] (#44357)
Wondershare
138 Patrones creacionales / Prototype PDFelement
#44357
[email protected] (#44357)
Wondershare
139 Patrones creacionales / Prototype PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Prototype nos permite producir co-
pias exactas de objetos geométricos sin acoplar el código a sus
clases.
1 // Prototipo base.
2 abstract class Shape is
3 field X: int
[email protected] (#44357)
Wondershare
140 Patrones creacionales / Prototype PDFelement
#44357
4 field Y: int
5 field color: string
6
7 // Un constructor normal.
8 constructor Shape() is
9 // ...
10
11 // El constructor prototipo. Un nuevo objeto se inicializa
12 // con valores del objeto existente.
13 constructor Shape(source: Shape) is
14 this
this()
15 this
this.X = source.X
16 this
this.Y = source.Y
17 this
this.color = source.color
18
19 // La operación clonar devuelve una de las subclases de
20 // Shape (Forma).
21 abstract method clone():Shape
22
23
24 // Prototipo concreto. El método de clonación crea un nuevo
25 // objeto y lo pasa al constructor. Hasta que el constructor
26 // termina, tiene una referencia a un nuevo clon. De este modo
27 // nadie tiene acceso a un clon a medio terminar. Esto garantiza
28 // la consistencia del resultado de la clonación.
29 class Rectangle extends Shape is
30 field width: int
31 field height: int
32
33 constructor Rectangle(source: Rectangle) is
34 // Para copiar campos privados definidos en la clase
35 // padre es necesaria una llamada a un constructor
[email protected] (#44357)
Wondershare
141 Patrones creacionales / Prototype PDFelement
#44357
36 // padre.
37 super
super(source)
38 this
this.width = source.width
39 this
this.height = source.height
40
41 method clone():Shape is
42 return new Rectangle(this
this)
43
44
45 class Circle extends Shape is
46 field radius: int
47
48 constructor Circle(source: Circle) is
49 super
super(source)
50 this
this.radius = source.radius
51
52 method clone():Shape is
53 return new Circle(this
this)
54
55
56 // En alguna parte del código cliente.
57 class Application is
58 field shapes: array of Shape
59
60 constructor Application() is
61 Circle circle = new Circle()
62 circle.X = 10
63 circle.Y = 10
64 circle.radius = 20
65 shapes.add(circle)
66
67 Circle anotherCircle = circle.clone()
[email protected] (#44357)
Wondershare
142 Patrones creacionales / Prototype PDFelement
#44357
68 shapes.add(anotherCircle)
69 // La variable `anotherCircle` (otroCírculo) contiene
70 // una copia exacta del objeto `circle`.
71
72 Rectangle rectangle = new Rectangle()
73 rectangle.width = 10
74 rectangle.height = 20
75 shapes.add(rectangle)
76
77 method businessLogic() is
78 // Prototype es genial porque te permite producir una
79 // copia de un objeto sin conocer nada de su tipo.
80 Array shapesCopy = new Array of Shapes.
81
82 // Por ejemplo, no conocemos los elementos exactos de la
83 // matriz de formas. Lo único que sabemos es que son
84 // todas formas. Pero, gracias al polimorfismo, cuando
85 // invocamos el método `clonar` en una forma, el
86 // programa comprueba su clase real y ejecuta el método
87 // de clonación adecuado definido en dicha clase. Por
88 // eso obtenemos los clones adecuados en lugar de un
89 // grupo de simples objetos Shape.
90 foreach (s in shapes) do
91 shapesCopy.add(s.clone())
92
93 // La matriz `shapesCopy` contiene copias exactas del
94 // hijo de la matriz `shape`.
[email protected] (#44357)
Wondershare
143 Patrones creacionales / Prototype PDFelement
#44357
Aplicabilidad
Utiliza el patrón Prototype cuando tu código no deba depender
de las clases concretas de objetos que necesites copiar.
[email protected] (#44357)
Wondershare
144 Patrones creacionales / Prototype PDFelement
#44357
Cómo implementarlo
1. Crea la interfaz del prototipo y declara el método clonar en
ella, o, simplemente, añade el método a todas las clases de
una jerarquía de clase existente, si la tienes.
[email protected] (#44357)
Wondershare
145 Patrones creacionales / Prototype PDFelement
#44357
Pros y contras
Puedes clonar objetos sin acoplarlos a sus clases concretas.
[email protected] (#44357)
Wondershare
146 Patrones creacionales / Prototype PDFelement
#44357
[email protected] (#44357)
Wondershare
147 Patrones creacionales / Prototype PDFelement
#44357
[email protected] (#44357)
Wondershare
148 Patrones creacionales / Singleton PDFelement
#44357
SINGLETON
También llamado: Instancia única
[email protected] (#44357)
Wondershare
149 Patrones creacionales / Singleton PDFelement
#44357
Problema
El patrón Singleton resuelve dos problemas al mismo tiempo,
vulnerando el Principio de responsabilidad única:
1. Garantizar que una clase tenga una única instancia. ¿Por qué
querría alguien controlar cuántas instancias tiene una clase?
El motivo más habitual es controlar el acceso a algún recurso
compartido, por ejemplo, una base de datos o un archivo.
Puede ser que los clientes ni siquiera se den cuenta de que trabajan con el
mismo objeto todo el tiempo.
[email protected] (#44357)
Wondershare
150 Patrones creacionales / Singleton PDFelement
#44357
Solución
Todas las implementaciones del patrón Singleton tienen estos
dos pasos en común:
[email protected] (#44357)
Wondershare
151 Patrones creacionales / Singleton PDFelement
#44357
[email protected] (#44357)
Wondershare
152 Patrones creacionales / Singleton PDFelement
#44357
Estructura
propia clase.
Pseudocódigo
En este ejemplo, la clase de conexión de la base de datos actúa
como Singleton. Esta clase no tiene un constructor público, por
lo que la única manera de obtener su objeto es invocando el
método obtenerInstancia . Este método almacena en caché
[email protected] (#44357)
Wondershare
153 Patrones creacionales / Singleton PDFelement
#44357
[email protected] (#44357)
Wondershare
154 Patrones creacionales / Singleton PDFelement
#44357
Aplicabilidad
Utiliza el patrón Singleton cuando una clase de tu programa
tan solo deba tener una instancia disponible para todos los
clientes; por ejemplo, un único objeto de base de datos com-
partido por distintas partes del programa.
[email protected] (#44357)
Wondershare
155 Patrones creacionales / Singleton PDFelement
#44357
Cómo implementarlo
1. Añade un campo estático privado a la clase para almacenar la
instancia Singleton.
[email protected] (#44357)
Wondershare
156 Patrones creacionales / Singleton PDFelement
#44357
Pros y contras
Puedes tener la certeza de que una clase tiene una única
instancia.
Obtienes un punto de acceso global a dicha instancia.
[email protected] (#44357)
Wondershare
157 Patrones creacionales / Singleton PDFelement
#44357
[email protected] (#44357)
Wondershare
158 Patrones estructurales PDFelement
#44357
Patrones estructurales
Los patrones estructurales explican cómo ensamblar objetos y
clases en estructuras más grandes, a la vez que se mantiene la
flexibilidad y eficiencia de estas estructuras.
Adapter
Permite la colaboración entre objetos con interfaces incompatib-
les.
Bridge
Permite dividir una clase grande o un grupo de clases estrecha-
mente relacionadas, en dos jerarquías separadas (abstracción e
implementación) que pueden desarrollarse independientemente
la una de la otra.
[email protected] (#44357)
Wondershare
159 Patrones estructurales PDFelement
#44357
Composite
Permite componer objetos en estructuras de árbol y trabajar con
esas estructuras como si fueran objetos individuales.
Decorator
Permite añadir funcionalidades a objetos colocando estos objetos
dentro de objetos encapsuladores especiales que contienen estas
funcionalidades.
Facade
Proporciona una interfaz simplificada a una biblioteca, un frame-
work o cualquier otro grupo complejo de clases.
[email protected] (#44357)
Wondershare
160 Patrones estructurales PDFelement
#44357
Flyweight
Permite mantener más objetos dentro de la cantidad disponible
de memoria RAM compartiendo las partes comunes del estado
entre varios objetos en lugar de mantener toda la información en
cada objeto.
Proxy
Permite proporcionar un sustituto o marcador de posición para
otro objeto. Un proxy controla el acceso al objeto original, permi-
tiéndote hacer algo antes o después de que la solicitud llegue al
objeto original.
[email protected] (#44357)
Wondershare
161 Patrones estructurales / Adapter PDFelement
#44357
ADAPTER
También llamado: Adaptador, Envoltorio, Wrapper
[email protected] (#44357)
Wondershare
162 Patrones estructurales / Adapter PDFelement
#44357
Problema
Imagina que estás creando una aplicación de monitoreo del
mercado de valores. La aplicación descarga la información de
bolsa desde varias fuentes en formato XML para presentarla al
usuario con bonitos gráficos y diagramas.
[email protected] (#44357)
Wondershare
163 Patrones estructurales / Adapter PDFelement
#44357
Solución
Puedes crear un adaptador. Se trata de un objeto especial que
convierte la interfaz de un objeto, de forma que otro objeto
pueda comprenderla.
[email protected] (#44357)
Wondershare
164 Patrones estructurales / Adapter PDFelement
#44357
[email protected] (#44357)
Wondershare
165 Patrones estructurales / Adapter PDFelement
#44357
Estructura
Adaptador de objetos
[email protected] (#44357)
Wondershare
166 Patrones estructurales / Adapter PDFelement
#44357
[email protected] (#44357)
Wondershare
167 Patrones estructurales / Adapter PDFelement
#44357
Clase adaptadora
[email protected] (#44357)
Wondershare
168 Patrones estructurales / Adapter PDFelement
#44357
Pseudocódigo
Este ejemplo del patrón Adapter se basa en el clásico conflicto
entre piezas cuadradas y agujeros redondos.
[email protected] (#44357)
Wondershare
169 Patrones estructurales / Adapter PDFelement
#44357
[email protected] (#44357)
Wondershare
170 Patrones estructurales / Adapter PDFelement
#44357
Aplicabilidad
Utiliza la clase adaptadora cuando quieras usar una clase exi-
stente, pero cuya interfaz no sea compatible con el resto del
código.
[email protected] (#44357)
Wondershare
171 Patrones estructurales / Adapter PDFelement
#44357
Cómo implementarlo
1. Asegúrate de que tienes al menos dos clases con interfaces in-
compatibles:
[email protected] (#44357)
Wondershare
172 Patrones estructurales / Adapter PDFelement
#44357
[email protected] (#44357)
Wondershare
173 Patrones estructurales / Adapter PDFelement
#44357
Pros y contras
Principio de responsabilidad única. Puedes separar la interfaz o
el código de conversión de datos de la lógica de negocio pri-
maria del programa.
Principio de abierto/cerrado. Puedes introducir nuevos tipos de
adaptadores al programa sin descomponer el código cliente
existente, siempre y cuando trabajen con los adaptadores a
través de la interfaz con el cliente.
[email protected] (#44357)
Wondershare
174 Patrones estructurales / Adapter PDFelement
#44357
[email protected] (#44357)
Wondershare
175 Patrones estructurales / Bridge PDFelement
#44357
BRIDGE
También llamado: Puente
[email protected] (#44357)
Wondershare
176 Patrones estructurales / Bridge PDFelement
#44357
Problema
¿Abstracción? ¿Implementación? ¿Asusta? Mantengamos la
calma y veamos un ejemplo sencillo.
[email protected] (#44357)
Wondershare
177 Patrones estructurales / Bridge PDFelement
#44357
Solución
Este problema se presenta porque intentamos extender las
clases de forma en dos dimensiones independientes: por forma
y por color. Es un problema muy habitual en la herencia de
clases.
[email protected] (#44357)
Wondershare
178 Patrones estructurales / Bridge PDFelement
#44357
Abstracción e implementación
1
El libro de la GoF introduce los términos Abstracción e Imp-
lementación como parte de la definición del patrón Bridge. En
mi opinión, los términos suenan demasiado académicos y pro-
vocan que el patrón parezca más complicado de lo que es en
realidad. Una vez leído el sencillo ejemplo con las formas y los
colores, vamos a descifrar el significado que esconden las te-
mibles palabras del libro de esta banda de cuatro.
[email protected] (#44357)
Wondershare
179 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
180 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
181 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
182 Patrones estructurales / Bridge PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
183 Patrones estructurales / Bridge PDFelement
#44357
Pseudocódigo
Este ejemplo ilustra cómo puede ayudar el patrón Bridge a di-
vidir el código monolítico de una aplicación que gestiona di-
spositivos y sus controles remotos. Las clases Dispositivo
actúan como implementación, mientras que las clases
Remoto actúan como abstracción.
[email protected] (#44357)
Wondershare
184 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
185 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
186 Patrones estructurales / Bridge PDFelement
#44357
28 device.setVolume(0)
29
30
31 // La interfaz de "implementación" declara métodos comunes a
32 // todas las clases concretas de implementación. No tiene por
33 // qué coincidir con la interfaz de la abstracción. De hecho,
34 // las dos interfaces pueden ser completamente diferentes.
35 // Normalmente, la interfaz de implementación únicamente
36 // proporciona operaciones primitivas, mientras que la
37 // abstracción define operaciones de más alto nivel con base en
38 // las primitivas.
39 interface Device is
40 method isEnabled()
41 method enable()
42 method disable()
43 method getVolume()
44 method setVolume(percent)
45 method getChannel()
46 method setChannel(channel)
47
48
49 // Todos los dispositivos siguen la misma interfaz.
50 class Tv implements Device is
51 // ...
52
53 class Radio implements Device is
54 // ...
55
56
57 // En algún lugar del código cliente.
58 tv = new Tv()
59 remote = new RemoteControl(tv)
[email protected] (#44357)
Wondershare
187 Patrones estructurales / Bridge PDFelement
#44357
60 remote.togglePower()
61
62 radio = new Radio()
63 remote = new AdvancedRemoteControl(radio)
Aplicabilidad
Utiliza el patrón Bridge cuando quieras dividir y organizar una
clase monolítica que tenga muchas variantes de una sola fun-
cionalidad (por ejemplo, si la clase puede trabajar con diversos
servidores de bases de datos).
[email protected] (#44357)
Wondershare
188 Patrones estructurales / Bridge PDFelement
#44357
Por cierto, este último punto es la razón principal por la que tanta
gente confunde el patrón Bridge con el patrón Strategy. Recuerda
que un patrón es algo más que un cierto modo de estructurar tus
clases. También puede comunicar intención y el tipo de problema
que se está abordando.
Cómo implementarlo
1. Identifica las dimensiones ortogonales de tus clases. Estos co-
nceptos independientes pueden ser: abstracción/plataforma,
dominio/infraestructura, front end/back end, o interfaz/imple-
mentación.
[email protected] (#44357)
Wondershare
189 Patrones estructurales / Bridge PDFelement
#44357
Pros y contras
Puedes crear clases y aplicaciones independientes de
plataforma.
El código cliente funciona con abstracciones de alto nivel. No
está expuesto a los detalles de la plataforma.
[email protected] (#44357)
Wondershare
190 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
191 Patrones estructurales / Bridge PDFelement
#44357
[email protected] (#44357)
Wondershare
192 Patrones estructurales / Composite PDFelement
#44357
COMPOSITE
También llamado: Objeto compuesto, Object Tree
[email protected] (#44357)
Wondershare
193 Patrones estructurales / Composite PDFelement
#44357
Problema
El uso del patrón Composite sólo tiene sentido cuando el modelo
central de tu aplicación puede representarse en forma de árbol.
[email protected] (#44357)
Wondershare
194 Patrones estructurales / Composite PDFelement
#44357
Solución
El patrón Composite sugiere que trabajes con Productos y
Cajas a través de una interfaz común que declara un método
[email protected] (#44357)
Wondershare
195 Patrones estructurales / Composite PDFelement
#44357
[email protected] (#44357)
Wondershare
196 Patrones estructurales / Composite PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
197 Patrones estructurales / Composite PDFelement
#44357
[email protected] (#44357)
Wondershare
198 Patrones estructurales / Composite PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Composite te permite implementar
el apilamiento (stacking) de formas geométricas en un editor
gráfico.
[email protected] (#44357)
Wondershare
199 Patrones estructurales / Composite PDFelement
#44357
que una forma simple. Sin embargo, en lugar de hacer algo por
su cuenta, una forma compuesta pasa la solicitud de forma re-
cursiva a todos sus hijos y “suma” el resultado.
[email protected] (#44357)
Wondershare
200 Patrones estructurales / Composite PDFelement
#44357
20 method draw() is
21 // Dibuja un punto en X e Y.
22
23 // Todas las clases de componente pueden extender otros
24 // componentes.
25 class Circle extends Dot is
26 field radius
27
28 constructor Circle(x, y, radius) { ... }
29
30 method draw() is
31 // Dibuja un círculo en X y Y con radio R.
32
33 // La clase compuesta representa componentes complejos que
34 // pueden tener hijos. Normalmente los objetos compuestos
35 // delegan el trabajo real a sus hijos y después "recapitulan"
36 // el resultado.
37 class CompoundGraphic implements Graphic is
38 field children: array of Graphic
39
40 // Un objeto compuesto puede añadir o eliminar otros
41 // componentes (tanto simples como complejos) a o desde su
42 // lista hija.
43 method add(child: Graphic) is
44 // Añade un hijo a la matriz de hijos.
45
46 method remove(child: Graphic) is
47 // Elimina un hijo de la matriz de hijos.
48
49 method move(x, y) is
50 foreach (child in children) do
51 child.move(x, y)
[email protected] (#44357)
Wondershare
201 Patrones estructurales / Composite PDFelement
#44357
52
53 // Un compuesto ejecuta su lógica primaria de una forma
54 // particular. Recorre recursivamente todos sus hijos,
55 // recopilando y recapitulando sus resultados. Debido a que
56 // los hijos del compuesto pasan esas llamadas a sus propios
57 // hijos y así sucesivamente, se recorre todo el árbol de
58 // objetos como resultado.
59 method draw() is
60 // 1. Para cada componente hijo:
61 // - Dibuja el componente.
62 // - Actualiza el rectángulo delimitador.
63 // 2. Dibuja un rectángulo de línea punteada utilizando
64 // las coordenadas de delimitación.
65
66
67 // El código cliente trabaja con todos los componentes a través
68 // de su interfaz base. De esta forma el código cliente puede
69 // soportar componentes de hoja simples así como compuestos
70 // complejos.
71 class ImageEditor is
72 field all: array of Graphic
73
74 method load() is
75 all = new CompoundGraphic()
76 all.add(new
new Dot(1, 2))
77 all.add(new
new Circle(5, 3, 10))
78 // ...
79
80 // Combina componentes seleccionados para formar un
81 // componente compuesto complejo.
82 method groupSelected(components: array of Graphic) is
83 group = new CompoundGraphic()
[email protected] (#44357)
Wondershare
202 Patrones estructurales / Composite PDFelement
#44357
Aplicabilidad
Utiliza el patrón Composite cuando tengas que implementar
una estructura de objetos con forma de árbol.
[email protected] (#44357)
Wondershare
203 Patrones estructurales / Composite PDFelement
#44357
Cómo implementarlo
1. Asegúrate de que el modelo central de tu aplicación pueda re-
presentarse como una estructura de árbol. Intenta dividirlo en
elementos simples y contenedores. Recuerda que los contene-
dores deben ser capaces de contener tanto elementos simples
como otros contenedores.
[email protected] (#44357)
Wondershare
204 Patrones estructurales / Composite PDFelement
#44357
Pros y contras
Puedes trabajar con estructuras de árbol complejas con mayor
comodidad: utiliza el polimorfismo y la recursión en tu favor.
Principio de abierto/cerrado. Puedes introducir nuevos tipos de
elemento en la aplicación sin descomponer el código existen-
te, que ahora funciona con el árbol de objetos.
[email protected] (#44357)
Wondershare
205 Patrones estructurales / Composite PDFelement
#44357
[email protected] (#44357)
Wondershare
206 Patrones estructurales / Decorator PDFelement
#44357
DECORATOR
También llamado: Decorador, Envoltorio, Wrapper
[email protected] (#44357)
Wondershare
207 Patrones estructurales / Decorator PDFelement
#44357
Problema
Imagina que estás trabajando en una biblioteca de notificacio-
nes que permite a otros programas notificar a sus usuarios ace-
rca de eventos importantes.
[email protected] (#44357)
Wondershare
208 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
209 Patrones estructurales / Decorator PDFelement
#44357
Solución
Cuando tenemos que alterar la funcionalidad de un objeto, lo
primero que se viene a la mente es extender una clase. No ob-
stante, la herencia tiene varias limitaciones importantes de las
que debes ser consciente.
[email protected] (#44357)
Wondershare
210 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
211 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
212 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
213 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
214 Patrones estructurales / Decorator PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
215 Patrones estructurales / Decorator PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Decorator te permite comprimir y
encriptar información delicada independientemente del códi-
go que utiliza esos datos.
[email protected] (#44357)
Wondershare
216 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
217 Patrones estructurales / Decorator PDFelement
#44357
• Después de que los datos son leídos del disco, pasan por los
mismos decoradores, que los descomprimen y decodifican.
[email protected] (#44357)
Wondershare
218 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
219 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
220 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
221 Patrones estructurales / Decorator PDFelement
#44357
121 if (enabledCompression)
122 source = new CompressionDecorator(source)
123
124 logger = new SalaryManager(source)
125 salary = logger.load()
126 // ...
Aplicabilidad
Utiliza el patrón Decorator cuando necesites asignar funciona-
lidades adicionales a objetos durante el tiempo de ejecución
sin descomponer el código que utiliza esos objetos.
[email protected] (#44357)
Wondershare
222 Patrones estructurales / Decorator PDFelement
#44357
Cómo implementarlo
1. Asegúrate de que tu dominio de negocio puede representar-
se como un componente primario con varias capas opcionales
encima.
4. Crea una clase base decoradora. Debe tener un campo para al-
macenar una referencia a un objeto envuelto. El campo debe
declararse con el tipo de interfaz de componente para permitir
la vinculación a componentes concretos, así como a decorado-
res. La clase decoradora base debe delegar todas las operacio-
nes al objeto envuelto.
[email protected] (#44357)
Wondershare
223 Patrones estructurales / Decorator PDFelement
#44357
Pros y contras
Puedes extender el comportamiento de un objeto sin crear una
nueva subclase.
Puedes añadir o eliminar responsabilidades de un objeto dura-
nte el tiempo de ejecución.
Puedes combinar varios comportamientos envolviendo un ob-
jeto con varios decoradores.
Principio de responsabilidad única. Puedes dividir una clase mo-
nolítica que implementa muchas variantes posibles de compo-
rtamiento, en varias clases más pequeñas.
[email protected] (#44357)
Wondershare
224 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
225 Patrones estructurales / Decorator PDFelement
#44357
[email protected] (#44357)
Wondershare
226 Patrones estructurales / Facade PDFelement
#44357
FACADE
También llamado: Fachada
[email protected] (#44357)
Wondershare
227 Patrones estructurales / Facade PDFelement
#44357
Problema
Imagina que debes lograr que tu código trabaje con un amplio
grupo de objetos que pertenecen a una sofisticada biblioteca o
framework. Normalmente, debes inicializar todos esos objetos,
llevar un registro de las dependencias, ejecutar los métodos
en el orden correcto y así sucesivamente.
Solución
Una fachada es una clase que proporciona una interfaz si-
mple a un subsistema complejo que contiene muchas partes
móviles. Una fachada puede proporcionar una funcionalidad
limitada en comparación con trabajar directamente con el sub-
sistema. Sin embargo, tan solo incluye las funciones realmente
importantes para los clientes.
[email protected] (#44357)
Wondershare
228 Patrones estructurales / Facade PDFelement
#44357
[email protected] (#44357)
Wondershare
229 Patrones estructurales / Facade PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
230 Patrones estructurales / Facade PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Facade simplifica la interacción con
un framework complejo de conversión de vídeo.
[email protected] (#44357)
Wondershare
231 Patrones estructurales / Facade PDFelement
#44357
[email protected] (#44357)
Wondershare
232 Patrones estructurales / Facade PDFelement
#44357
27 class VideoConverter is
28 method convert(filename, format):File is
29 file = new VideoFile(filename)
30 sourceCodec = new CodecFactory.extract(file)
31 if (format == "mp4")
32 destinationCodec = new MPEG4CompressionCodec()
33 else
34 destinationCodec = new OggCompressionCodec()
35 buffer = BitrateReader.read(filename, sourceCodec)
36 result = BitrateReader.convert(buffer, destinationCodec)
37 result = (new
new AudioMixer()).fix(result)
38 return new File(result)
39
40 // Las clases Application no dependen de un millón de clases
41 // proporcionadas por el complejo framework. Además, si decides
42 // cambiar los frameworks, sólo tendrás de volver a escribir la
43 // clase fachada.
44 class Application is
45 method main() is
46 convertor = new VideoConverter()
47 mp4 = convertor.convert("funny-cats-video.ogg", "mp4")
48 mp4.save()
Aplicabilidad
Utiliza el patrón Facade cuando necesites una interfaz limitada
pero directa a un subsistema complejo.
[email protected] (#44357)
Wondershare
233 Patrones estructurales / Facade PDFelement
#44357
Cómo implementarlo
1. Comprueba si es posible proporcionar una interfaz más simple
que la que está proporcionando un subsistema existente. Estás
bien encaminado si esta interfaz hace que el código cliente sea
independiente de muchas de las clases del subsistema.
[email protected] (#44357)
Wondershare
234 Patrones estructurales / Facade PDFelement
#44357
Pros y contras
Puedes aislar tu código de la complejidad de un subsistema.
[email protected] (#44357)
Wondershare
235 Patrones estructurales / Facade PDFelement
#44357
[email protected] (#44357)
Wondershare
236 Patrones estructurales / Facade PDFelement
#44357
[email protected] (#44357)
Wondershare
237 Patrones estructurales / Flyweight PDFelement
#44357
FLYWEIGHT
También llamado: Peso mosca, Peso ligero, Cache
[email protected] (#44357)
Wondershare
238 Patrones estructurales / Flyweight PDFelement
#44357
Problema
Para divertirte un poco después de largas horas de trabajo, de-
cides crear un sencillo videojuego en el que los jugadores se
tienen que mover por un mapa disparándose entre sí. Decides
implementar un sistema de partículas realistas que lo distinga
de otros juegos. Grandes cantidades de balas, misiles y metral-
la de las explosiones volarán por todo el mapa, ofreciendo una
apasionante experiencia al jugador.
[email protected] (#44357)
Wondershare
239 Patrones estructurales / Flyweight PDFelement
#44357
Solución
Observando más atentamente la clase Partícula , puede ser
que te hayas dado cuenta de que los campos de color y spri-
te consumen mucha más memoria que otros campos. Lo que
es peor, esos dos campos almacenan información casi idéntica
de todas las partículas. Por ejemplo, todas las balas tienen el
mismo color y sprite.
[email protected] (#44357)
Wondershare
240 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
241 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
242 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
243 Patrones estructurales / Flyweight PDFelement
#44357
Flyweight y la inmutabilidad
Fábrica flyweight
[email protected] (#44357)
Wondershare
244 Patrones estructurales / Flyweight PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
245 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
246 Patrones estructurales / Flyweight PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Flyweight ayuda a reducir el uso de
memoria a la hora de representar millones de objetos de árbol
en un lienzo.
[email protected] (#44357)
Wondershare
247 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
248 Patrones estructurales / Flyweight PDFelement
#44357
33
34 // El objeto contextual contiene la parte extrínseca del estado
35 // del árbol. Una aplicación puede crear millones de ellas, ya
36 // que son muy pequeñas: dos coordenadas en números enteros y un
37 // campo de referencia.
38 class Tree is
39 field x,y
40 field type: TreeType
41 constructor Tree(x, y, type) { ... }
42 method draw(canvas) is
43 type.draw(canvas, this
this.x, this
this.y)
44
45 // Las clases Tree y Forest son los clientes de flyweight.
46 // Puedes fusionarlas si no tienes la intención de desarrollar
47 // más la clase Tree.
48 class Forest is
49 field trees: collection of Trees
50
51 method plantTree(x, y, name, color, texture) is
52 type = TreeFactory.getTreeType(name, color, texture)
53 tree = new Tree(x, y, type)
54 trees.add(tree)
55
56 method draw(canvas) is
57 foreach (tree in trees) do
58 tree.draw(canvas)
[email protected] (#44357)
Wondershare
249 Patrones estructurales / Flyweight PDFelement
#44357
Aplicabilidad
Utiliza el patrón Flyweight únicamente cuando tu programa
deba soportar una enorme cantidad de objetos que apenas
quepan en la RAM disponible.
Cómo implementarlo
1. Divide los campos de una clase que se convertirá en flyweight
en dos partes:
[email protected] (#44357)
Wondershare
250 Patrones estructurales / Flyweight PDFelement
#44357
Pros y contras
Puedes ahorrar mucha RAM, siempre que tu programa tenga
toneladas de objetos similares.
Puede que estés cambiando RAM por ciclos CPU cuando deba
calcularse de nuevo parte de la información de contexto cada
vez que alguien invoque un método flyweight.
[email protected] (#44357)
Wondershare
251 Patrones estructurales / Flyweight PDFelement
#44357
[email protected] (#44357)
Wondershare
252 Patrones estructurales / Proxy PDFelement
#44357
PROXY
Proxy es un patrón de diseño estructural que te permite propo-
rcionar un sustituto o marcador de posición para otro objeto.
Un proxy controla el acceso al objeto original, permitiéndote
hacer algo antes o después de que la solicitud llegue al obje-
to original.
[email protected] (#44357)
Wondershare
253 Patrones estructurales / Proxy PDFelement
#44357
Problema
¿Por qué querrías controlar el acceso a un objeto? Imagina que
tienes un objeto enorme que consume una gran cantidad de
recursos del sistema. Lo necesitas de vez en cuando, pero no
siempre.
[email protected] (#44357)
Wondershare
254 Patrones estructurales / Proxy PDFelement
#44357
Solución
El patrón Proxy sugiere que crees una nueva clase proxy con la
misma interfaz que un objeto de servicio original. Después ac-
tualizas tu aplicación para que pase el objeto proxy a todos los
clientes del objeto original. Al recibir una solicitud de un clie-
nte, el proxy crea un objeto de servicio real y le delega todo el
trabajo.
[email protected] (#44357)
Wondershare
255 Patrones estructurales / Proxy PDFelement
#44357
Las tarjetas de crédito pueden utilizarse para realizar pagos tanto como
el efectivo.
[email protected] (#44357)
Wondershare
256 Patrones estructurales / Proxy PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
257 Patrones estructurales / Proxy PDFelement
#44357
Pseudocódigo
Este ejemplo ilustra cómo el patrón Proxy puede ayudar a int-
roducir la inicialización diferida y el almacenamiento en caché
a una biblioteca de integración de YouTube de un tercero.
[email protected] (#44357)
Wondershare
258 Patrones estructurales / Proxy PDFelement
#44357
[email protected] (#44357)
Wondershare
259 Patrones estructurales / Proxy PDFelement
#44357
[email protected] (#44357)
Wondershare
260 Patrones estructurales / Proxy PDFelement
#44357
53
54 // La clase GUI, que solía trabajar directamente con un objeto
55 // de servicio, permanece sin cambios siempre y cuando trabaje
56 // con el objeto de servicio a través de una interfaz. Podemos
57 // pasar sin riesgo un objeto proxy en lugar de un objeto de
58 // servicio real, ya que ambos implementan la misma interfaz.
59 class YouTubeManager is
60 protected field service: ThirdPartyYouTubeLib
61
62 constructor YouTubeManager(service: ThirdPartyYouTubeLib) is
63 this
this.service = service
64
65 method renderVideoPage(id) is
66 info = service.getVideoInfo(id)
67 // Representa la página del video.
68
69 method renderListPanel() is
70 list = service.listVideos()
71 // Representa la lista de miniaturas de los videos.
72
73 method reactOnUserInput() is
74 renderVideoPage()
75 renderListPanel()
76
77 // La aplicación puede configurar proxies sobre la marcha.
78 class Application is
79 method init() is
80 aYouTubeService = new ThirdPartyYouTubeClass()
81 aYouTubeProxy = new CachedYouTubeClass(aYouTubeService)
82 manager = new YouTubeManager(aYouTubeProxy)
83 manager.reactOnUserInput()
[email protected] (#44357)
Wondershare
261 Patrones estructurales / Proxy PDFelement
#44357
Aplicabilidad
Hay decenas de formas de utilizar el patrón Proxy. Repasemos
los usos más populares.
[email protected] (#44357)
Wondershare
262 Patrones estructurales / Proxy PDFelement
#44357
[email protected] (#44357)
Wondershare
263 Patrones estructurales / Proxy PDFelement
#44357
Cómo implementarlo
1. Si no hay una interfaz de servicio preexistente, crea una para
que los objetos de proxy y de servicio sean intercambiables.
No siempre resulta posible extraer la interfaz de la clase ser-
vicio, porque tienes que cambiar todos los clientes del servi-
cio para utilizar esa interfaz. El plan B consiste en convertir el
proxy en una subclase de la clase servicio, de forma que here-
de la interfaz del servicio.
[email protected] (#44357)
Wondershare
264 Patrones estructurales / Proxy PDFelement
#44357
Pros y contras
Puedes controlar el objeto de servicio sin que los clientes
lo sepan.
Puedes gestionar el ciclo de vida del objeto de servicio cuando
a los clientes no les importa.
El proxy funciona incluso si el objeto de servicio no está listo
o no está disponible.
Principio de abierto/cerrado. Puedes introducir nuevos proxies
sin cambiar el servicio o los clientes.
[email protected] (#44357)
Wondershare
265 Patrones estructurales / Proxy PDFelement
#44357
[email protected] (#44357)
Wondershare
266 Patrones de comportamiento PDFelement
#44357
Patrones de
comportamiento
Los patrones de comportamiento tratan con algoritmos y la
asignación de responsabilidades entre objetos.
Chain of
Responsibility
Permite pasar solicitudes a lo largo de una cadena de manejado-
res. Al recibir una solicitud, cada manejador decide si la procesa
o si la pasa al siguiente manejador de la cadena.
Command
Convierte una solicitud en un objeto independiente que contiene
toda la información sobre la solicitud. Esta transformación te per-
mite parametrizar los métodos con diferentes solicitudes, retrasar
o poner en cola la ejecución de una solicitud y soportar operacio-
nes que no se pueden realizar.
[email protected] (#44357)
Wondershare
267 Patrones de comportamiento PDFelement
#44357
Iterator
Permite recorrer elementos de una colección sin exponer su rep-
resentación subyacente (lista, pila, árbol, etc.).
Mediator
Permite reducir las dependencias caóticas entre objetos. El pat-
rón restringe las comunicaciones directas entre los objetos, for-
zándolos a colaborar únicamente a través de un objeto mediador.
Memento
Permite guardar y restaurar el estado previo de un objeto sin re-
velar los detalles de su implementación.
[email protected] (#44357)
Wondershare
268 Patrones de comportamiento PDFelement
#44357
Observer
Permite definir un mecanismo de suscripción para notificar a va-
rios objetos sobre cualquier evento que le suceda al objeto que
están observando.
State
Permite a un objeto alterar su comportamiento cuando su estado
interno cambia. Parece como si el objeto cambiara su clase.
Strategy
Permite definir una familia de algoritmos, colocar cada uno de
ellos en una clase separada y hacer sus objetos intercambiables.
[email protected] (#44357)
Wondershare
269 Patrones de comportamiento PDFelement
#44357
Template
Method
Define el esqueleto de un algoritmo en la superclase pero permi-
te que las subclases sobrescriban pasos del algoritmo sin cam-
biar su estructura.
Visitor
Permite separar algoritmos de los objetos sobre los que operan.
[email protected] (#44357)
Wondershare
270 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
CHAIN OF
RESPONSIBILITY
También llamado: Cadena de responsabilidad, CoR, Chain of
Command
[email protected] (#44357)
Wondershare
271 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Problema
Imagina que estás trabajando en un sistema de pedidos online.
Quieres restringir el acceso al sistema de forma que únicamen-
te los usuarios autenticados puedan generar pedidos. Además,
los usuarios que tengan permisos administrativos deben tener
pleno acceso a todos los pedidos.
[email protected] (#44357)
Wondershare
272 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
273 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Solución
Al igual que muchos otros patrones de diseño de comporta-
miento, el Chain of Responsibility se basa en transformar co-
mportamientos particulares en objetos autónomos llamados
manejadores. En nuestro caso, cada comprobación debe pone-
rse dentro de su propia clase con un único método que reali-
ce la comprobación. La solicitud, junto con su información, se
pasa a este método como argumento.
[email protected] (#44357)
Wondershare
274 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
275 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
276 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
277 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
278 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
279 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Chain of Responsibility es respon-
sable de mostrar información de ayuda contextual para eleme-
ntos GUI activos.
Las clases GUI se crean con el patrón Composite. Cada elemento se vincula
a su elemento contenedor. En cualquier momento puedes crear una cadena
de elementos que comience con el propio elemento y recorra todos los
elementos contenedores.
[email protected] (#44357)
Wondershare
280 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
281 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
282 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
283 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
284 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Aplicabilidad
Utiliza el patrón Chain of Responsibility cuando tu programa
deba procesar distintos tipos de solicitudes de varias maneras,
pero los tipos exactos de solicitudes y sus secuencias no se co-
nozcan de antemano.
[email protected] (#44357)
Wondershare
285 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
Cómo implementarlo
1. Declara la interfaz manejadora y describe la firma de un méto-
do para manejar solicitudes.
[email protected] (#44357)
Wondershare
286 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
◦ Si procesa la solicitud.
Pros y contras
Puedes controlar el orden de control de solicitudes.
[email protected] (#44357)
Wondershare
287 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
288 Patrones de comportamiento / Chain of Responsibility PDFelement
#44357
[email protected] (#44357)
Wondershare
289 Patrones de comportamiento / Command PDFelement
#44357
COMMAND
También llamado: Comando, Orden, Action, Transaction
[email protected] (#44357)
Wondershare
290 Patrones de comportamiento / Command PDFelement
#44357
Problema
Imagina que estás trabajando en una nueva aplicación de edi-
ción de texto. Tu tarea actual consiste en crear una barra de
herramientas con unos cuantos botones para varias opera-
ciones del editor. Creaste una clase Botón muy limpia que
puede utilizarse para los botones de la barra de herramientas
y también para botones genéricos en diversos diálogos.
[email protected] (#44357)
Wondershare
291 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
292 Patrones de comportamiento / Command PDFelement
#44357
Solución
El buen diseño de software a menudo se basa en el principio
de separación de responsabilidades, lo que suele tener como
resultado la división de la aplicación en capas. El ejemplo más
habitual es tener una capa para la interfaz gráfica de usua-
rio (GUI) y otra capa para la lógica de negocio. La capa GUI
es responsable de representar una bonita imagen en pantalla,
capturar entradas y mostrar resultados de lo que el usuario y
la aplicación están haciendo. Sin embargo, cuando se trata de
hacer algo importante, como calcular la trayectoria de la luna
o componer un informe anual, la capa GUI delega el trabajo a
la capa subyacente de la lógica de negocio.
[email protected] (#44357)
Wondershare
293 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
294 Patrones de comportamiento / Command PDFelement
#44357
Puede que hayas observado que falta una pieza del rompeca-
bezas, que son los parámetros de la solicitud. Un objeto GUI
puede haber proporcionado al objeto de la capa de negocio al-
gunos parámetros. Ya que el método de ejecución del coma-
ndo no tiene parámetros, ¿cómo pasaremos los detalles de la
solicitud al receptor? Resulta que el comando debe estar pre-
configurado con esta información o ser capaz de conseguirla
por su cuenta.
[email protected] (#44357)
Wondershare
295 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
296 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
297 Patrones de comportamiento / Command PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
298 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
299 Patrones de comportamiento / Command PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Command ayuda a rastrear el histo-
rial de operaciones ejecutadas y hace posible revertir una ope-
ración si es necesario.
[email protected] (#44357)
Wondershare
300 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
301 Patrones de comportamiento / Command PDFelement
#44357
18 editor.text = backup
19
20 // El método de ejecución se declara abstracto para forzar a
21 // todos los comandos concretos a proporcionar sus propias
22 // implementaciones. El método debe devolver verdadero o
23 // falso dependiendo de si el comando cambia el estado del
24 // editor.
25 abstract method execute()
26
27
28 // Los comandos concretos van aquí.
29 class CopyCommand extends Command is
30 // El comando copiar no se guarda en el historial ya que no
31 // cambia el estado del editor.
32 method execute() is
33 app.clipboard = editor.getSelection()
34 return false
35
36 class CutCommand extends Command is
37 // El comando cortar no cambia el estado del editor, por lo
38 // que debe guardarse en el historial. Y se guardará siempre
39 // y cuando el método devuelva verdadero.
40 method execute() is
41 saveBackup()
42 app.clipboard = editor.getSelection()
43 editor.deleteSelection()
44 return true
45
46 class PasteCommand extends Command is
47 method execute() is
48 saveBackup()
49 editor.replaceSelection(app.clipboard)
[email protected] (#44357)
Wondershare
302 Patrones de comportamiento / Command PDFelement
#44357
50 return true
51
52 // La operación deshacer también es un comando.
53 class UndoCommand extends Command is
54 method execute() is
55 app.undo()
56 return false
57
58
59 // El historial global de comandos tan solo es una pila.
60 class CommandHistory is
61 private field history: array of Command
62
63 // El último dentro...
64 method push(c: Command) is
65 // Empuja el comando al final de la matriz del
66 // historial.
67
68 // ...el primero fuera.
69 method pop():Command is
70 // Obtiene el comando más reciente del historial.
71
72
73 // La clase editora tiene operaciones reales de edición de
74 // texto. Juega el papel de un receptor: todos los comandos
75 // acaban delegando la ejecución a los métodos del editor.
76 class Editor is
77 field text: string
78
79 method getSelection() is
80 // Devuelve el texto seleccionado.
81
[email protected] (#44357)
Wondershare
303 Patrones de comportamiento / Command PDFelement
#44357
82 method deleteSelection() is
83 // Borra el texto seleccionado.
84
85 method replaceSelection(text) is
86 // Inserta los contenidos del portapapeles en la
87 // posición actual.
88
89
90 // La clase Aplicación establece relaciones entre objetos. Actúa
91 // como un emisor: cuando algo debe hacerse, crea un objeto de
92 // comando y lo ejecuta.
93 class Application is
94 field clipboard: string
95 field editors: array of Editors
96 field activeEditor: Editor
97 field history: CommandHistory
98
99 // El código que asigna comandos a objetos UI puede tener
100 // este aspecto.
101 method createUI() is
102 // ...
103 copy = function
function() { executeCommand(
104 new CopyCommand(this
this, activeEditor)) }
105 copyButton.setCommand(copy)
106 shortcuts.onKeyPress("Ctrl+C", copy)
107
108 cut = function
function() { executeCommand(
109 new CutCommand(this
this, activeEditor)) }
110 cutButton.setCommand(cut)
111 shortcuts.onKeyPress("Ctrl+X", cut)
112
113 paste = function
function() { executeCommand(
[email protected] (#44357)
Wondershare
304 Patrones de comportamiento / Command PDFelement
#44357
Aplicabilidad
Utiliza el patrón Command cuando quieras parametrizar obje-
tos con operaciones.
[email protected] (#44357)
Wondershare
305 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
306 Patrones de comportamiento / Command PDFelement
#44357
Cómo implementarlo
1. Declara la interfaz de comando con un único método de
ejecución.
[email protected] (#44357)
Wondershare
307 Patrones de comportamiento / Command PDFelement
#44357
◦ Crear receptores.
Pros y contras
Principio de responsabilidad única. Puedes desacoplar las clases
que invocan operaciones de las que realizan esas operaciones.
Principio de abierto/cerrado. Puedes introducir nuevos coma-
ndos en la aplicación sin descomponer el código cliente
existente.
Puedes implementar deshacer/rehacer.
[email protected] (#44357)
Wondershare
308 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
309 Patrones de comportamiento / Command PDFelement
#44357
[email protected] (#44357)
Wondershare
310 Patrones de comportamiento / Iterator PDFelement
#44357
ITERATOR
También llamado: Iterador
[email protected] (#44357)
Wondershare
311 Patrones de comportamiento / Iterator PDFelement
#44357
Problema
Las colecciones son de los tipos de datos más utilizados en
programación. Sin embargo, una colección tan solo es un con-
tenedor para un grupo de objetos.
[email protected] (#44357)
Wondershare
312 Patrones de comportamiento / Iterator PDFelement
#44357
Por otro lado, el código cliente que debe funcionar con varias
colecciones puede no saber cómo éstas almacenan sus eleme-
ntos. No obstante, ya que todas las colecciones proporcionan
formas diferentes de acceder a sus elementos, no tienes otra
opción más que acoplar tu código a las clases de la colección
específica.
Solución
La idea central del patrón Iterator es extraer el comportamie-
nto de recorrido de una colección y colocarlo en un objeto in-
dependiente llamado iterador.
[email protected] (#44357)
Wondershare
313 Patrones de comportamiento / Iterator PDFelement
#44357
[email protected] (#44357)
Wondershare
314 Patrones de comportamiento / Iterator PDFelement
#44357
Planeas visitar Roma por unos días y ver todas sus atraccio-
nes y puntos de interés. Pero, una vez allí, podrías perder
mucho tiempo dando vueltas, incapaz de encontrar siquiera el
Coliseo.
[email protected] (#44357)
Wondershare
315 Patrones de comportamiento / Iterator PDFelement
#44357
[email protected] (#44357)
Wondershare
316 Patrones de comportamiento / Iterator PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
317 Patrones de comportamiento / Iterator PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Iterator se utiliza para recorrer un
tipo especial de colección que encapsula el acceso al grafo so-
cial de Facebook. La colección proporciona varios iteradores
que recorren perfiles de distintas formas.
[email protected] (#44357)
Wondershare
318 Patrones de comportamiento / Iterator PDFelement
#44357
[email protected] (#44357)
Wondershare
319 Patrones de comportamiento / Iterator PDFelement
#44357
[email protected] (#44357)
Wondershare
320 Patrones de comportamiento / Iterator PDFelement
#44357
26
27
28 // La clase iteradora concreta.
29 class FacebookIterator implements ProfileIterator is
30 // El iterador necesita una referencia a la colección que
31 // recorre.
32 private field facebook: Facebook
33 private field profileId, type: string
34
35 // Un objeto iterador recorre la colección
36 // independientemente de otro iterador, por eso debe
37 // almacenar el estado de iteración.
38 private field currentPosition
39 private field cache: array of Profile
40
41 constructor FacebookIterator(facebook, profileId, type) is
42 this
this.facebook = facebook
43 this
this.profileId = profileId
44 this
this.type = type
45
46 private method lazyInit() is
47 if (cache == null
null)
48 cache = facebook.socialGraphRequest(profileId, type)
49
50 // Cada clase iteradora concreta tiene su propia
51 // implementación de la interfaz iteradora común.
52 method getNext() is
53 if (hasMore())
54 currentPosition++
55 return cache[currentPosition]
56
57 method hasMore() is
[email protected] (#44357)
Wondershare
321 Patrones de comportamiento / Iterator PDFelement
#44357
58 lazyInit()
59 return currentPosition < cache.length
60
61
62 // Aquí tienes otro truco útil: puedes pasar un iterador a una
63 // clase cliente en lugar de darle acceso a una colección
64 // completa. De esta forma, no expones la colección al cliente.
65 //
66 // Y hay otra ventaja: puedes cambiar la forma en la que el
67 // cliente trabaja con la colección durante el tiempo de
68 // ejecución pasándole un iterador diferente. Esto es posible
69 // porque el código cliente no está acoplado a clases iteradoras
70 // concretas.
71 class SocialSpammer is
72 method send(iterator: ProfileIterator, message: string) is
73 while (iterator.hasMore())
74 profile = iterator.getNext()
75 System.sendEmail(profile.getEmail(), message)
76
77
78 // La clase Aplicación configura colecciones e iteradores y
79 // después los pasa al código cliente.
80 class Application is
81 field network: SocialNetwork
82 field spammer: SocialSpammer
83
84 method config() is
85 if working with Facebook
86 this
this.network = new Facebook()
87 if working with LinkedIn
88 this
this.network = new LinkedIn()
89 this
this.spammer = new SocialSpammer()
[email protected] (#44357)
Wondershare
322 Patrones de comportamiento / Iterator PDFelement
#44357
90
91 method sendSpamToFriends(profile) is
92 iterator = network.createFriendsIterator(profile.getId())
93 spammer.send(iterator, "Very important message")
94
95 method sendSpamToCoworkers(profile) is
96 iterator = network.createCoworkersIterator(profile.getId())
97 spammer.send(iterator, "Very important message")
Aplicabilidad
Utiliza el patrón Iterator cuando tu colección tenga una estruc-
tura de datos compleja a nivel interno, pero quieras ocultar su
complejidad a los clientes (ya sea por conveniencia o por razo-
nes de seguridad).
[email protected] (#44357)
Wondershare
323 Patrones de comportamiento / Iterator PDFelement
#44357
Cómo implementarlo
1. Declara la interfaz iteradora. Como mínimo, debe tener un
método para extraer el siguiente elemento de una colección.
Por conveniencia, puedes añadir un par de métodos distintos,
como para extraer el elemento previo, localizar la posición ac-
tual o comprobar el final de la iteración.
[email protected] (#44357)
Wondershare
324 Patrones de comportamiento / Iterator PDFelement
#44357
Pros y contras
Principio de responsabilidad única. Puedes limpiar el código
cliente y las colecciones extrayendo algoritmos de recorrido
voluminosos y colocándolos en clases independientes.
Principio de abierto/cerrado. Puedes implementar nuevos tipos
de colecciones e iteradores y pasarlos al código existente sin
descomponer nada.
Puedes recorrer la misma colección en paralelo porque cada
objeto iterador contiene su propio estado de iteración.
[email protected] (#44357)
Wondershare
325 Patrones de comportamiento / Iterator PDFelement
#44357
• Puedes utilizar Visitor junto con Iterator para recorrer una es-
tructura de datos compleja y ejecutar alguna operación sobre
sus elementos, incluso aunque todos tengan clases distintas.
[email protected] (#44357)
Wondershare
326 Patrones de comportamiento / Mediator PDFelement
#44357
MEDIATOR
También llamado: Mediador, Intermediary, Controller
[email protected] (#44357)
Wondershare
327 Patrones de comportamiento / Mediator PDFelement
#44357
Problema
Digamos que tienes un diálogo para crear y editar perfiles de
cliente. Consiste en varios controles de formulario, como cam-
pos de texto, casillas, botones, etc.
[email protected] (#44357)
Wondershare
328 Patrones de comportamiento / Mediator PDFelement
#44357
Los elementos pueden tener muchas relaciones con otros elementos. Por
eso, los cambios en algunos elementos pueden afectar a los demás.
Solución
El patrón Mediator sugiere que detengas toda comunicación
directa entre los componentes que quieres hacer independien-
tes entre sí. En lugar de ello, estos componentes deberán cola-
borar indirectamente, invocando un objeto mediador especial
que redireccione las llamadas a los componentes adecuados.
Como resultado, los componentes dependen únicamente de
una sola clase mediadora, en lugar de estar acoplados a dece-
nas de sus colegas.
[email protected] (#44357)
Wondershare
329 Patrones de comportamiento / Mediator PDFelement
#44357
[email protected] (#44357)
Wondershare
330 Patrones de comportamiento / Mediator PDFelement
#44357
Los pilotos de los aviones que llegan o salen del área de con-
trol del aeropuerto no se comunican directamente entre sí. En
lugar de eso, hablan con un controlador de tráfico aéreo, que
está sentado en una torre alta cerca de la pista de aterrizaje.
[email protected] (#44357)
Wondershare
331 Patrones de comportamiento / Mediator PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
332 Patrones de comportamiento / Mediator PDFelement
#44357
[email protected] (#44357)
Wondershare
333 Patrones de comportamiento / Mediator PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Mediator te ayuda a eliminar depe-
ndencias mutuas entre varias clases UI: botones, casillas y eti-
quetas de texto.
[email protected] (#44357)
Wondershare
334 Patrones de comportamiento / Mediator PDFelement
#44357
[email protected] (#44357)
Wondershare
335 Patrones de comportamiento / Mediator PDFelement
#44357
[email protected] (#44357)
Wondershare
336 Patrones de comportamiento / Mediator PDFelement
#44357
[email protected] (#44357)
Wondershare
337 Patrones de comportamiento / Mediator PDFelement
#44357
Aplicabilidad
Utiliza el patrón Mediator cuando resulte difícil cambiar algu-
nas de las clases porque están fuertemente acopladas a un pu-
ñado de otras clases.
[email protected] (#44357)
Wondershare
338 Patrones de comportamiento / Mediator PDFelement
#44357
Cómo implementarlo
1. Identifica un grupo de clases fuertemente acopladas que se
beneficiarían de ser más independientes (p. ej., para un mante-
nimiento más sencillo o una reutilización más simple de esas
clases).
[email protected] (#44357)
Wondershare
339 Patrones de comportamiento / Mediator PDFelement
#44357
Pros y contras
• Principio de responsabilidad única. Puedes extraer las comu-
nicaciones entre varios componentes dentro de un único sitio,
haciéndolo más fácil de comprender y mantener.
[email protected] (#44357)
Wondershare
340 Patrones de comportamiento / Memento PDFelement
#44357
MEMENTO
También llamado: Recuerdo, Instantánea, Snapshot
[email protected] (#44357)
Wondershare
341 Patrones de comportamiento / Memento PDFelement
#44357
Problema
Imagina que estás creando una aplicación de edición de texto.
Además de editar texto, tu programa puede formatearlo, asi
como insertar imágenes en línea, etc.
[email protected] (#44357)
Wondershare
342 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
343 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
344 Patrones de comportamiento / Memento PDFelement
#44357
Solución
Todos los problemas que hemos experimentado han sido pro-
vocados por una encapsulación fragmentada. Algunos objetos
intentan hacer más de lo que deben. Para recopilar los datos
necesarios para realizar una acción, invaden el espacio privado
de otros objetos en lugar de permitir a esos objetos realizar la
propia acción.
[email protected] (#44357)
Wondershare
345 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
346 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
347 Patrones de comportamiento / Memento PDFelement
#44357
Estructura
Implementación basada en clases anidadas
[email protected] (#44357)
Wondershare
348 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
349 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
350 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
351 Patrones de comportamiento / Memento PDFelement
#44357
Pseudocódigo
Este ejemplo utiliza el patrón Memento junto al patrón Co-
mmand para almacenar instantáneas del estado complejo del
editor de texto y restaurar un estado previo a partir de estas
instantáneas cuando sea necesario.
[email protected] (#44357)
Wondershare
352 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
353 Patrones de comportamiento / Memento PDFelement
#44357
24
25 // La clase memento almacena el estado pasado del editor.
26 class Snapshot is
27 private field editor: Editor
28 private field text, curX, curY, selectionWidth
29
30 constructor Snapshot(editor, text, curX, curY, selectionWidth) is
31 this
this.editor = editor
32 this
this.text = text
33 this
this.curX = curX
34 this
this.curY = curY
35 this
this.selectionWidth = selectionWidth
36
37 // En cierto punto, puede restaurarse un estado previo del
38 // editor utilizando un objeto memento.
39 method restore() is
40 editor.setText(text)
41 editor.setCursor(curX, curY)
42 editor.setSelectionWidth(selectionWidth)
43
44 // Un objeto de comando puede actuar como cuidador. En este
45 // caso, el comando obtiene un memento justo antes de cambiar el
46 // estado del originador. Cuando se solicita deshacer, restaura
47 // el estado del originador a partir del memento.
48 class Command is
49 private field backup: Snapshot
50
51 method makeBackup() is
52 backup = editor.createSnapshot()
53
54 method undo() is
55 if (backup != null
null)
[email protected] (#44357)
Wondershare
354 Patrones de comportamiento / Memento PDFelement
#44357
56 backup.restore()
57 // ...
Aplicabilidad
Utiliza el patrón Memento cuando quieras producir instantá-
neas del estado del objeto para poder restaurar un estado pre-
vio del objeto.
[email protected] (#44357)
Wondershare
355 Patrones de comportamiento / Memento PDFelement
#44357
Cómo implementarlo
1. Determina qué clase jugará el papel de la originadora. Es im-
portante saber si el programa utiliza un objeto central de este
tipo o varios más pequeños.
El tipo de retorno del método debe ser del mismo que la in-
terfaz que extrajiste en el paso anterior (asumiendo que lo hi-
[email protected] (#44357)
Wondershare
356 Patrones de comportamiento / Memento PDFelement
#44357
Pros y contras
Puedes producir instantáneas del estado del objeto sin violar
su encapsulación.
[email protected] (#44357)
Wondershare
357 Patrones de comportamiento / Memento PDFelement
#44357
[email protected] (#44357)
Wondershare
358 Patrones de comportamiento / Observer PDFelement
#44357
OBSERVER
También llamado: Observador, Publicación-Suscripción, Modelo-
patrón, Event-Subscriber, Listener
[email protected] (#44357)
Wondershare
359 Patrones de comportamiento / Observer PDFelement
#44357
Problema
Imagina que tienes dos tipos de objetos: un objeto Cliente
y un objeto Tienda . El cliente está muy interesado en una
marca particular de producto (digamos, un nuevo modelo de
iPhone) que estará disponible en la tienda muy pronto.
[email protected] (#44357)
Wondershare
360 Patrones de comportamiento / Observer PDFelement
#44357
Solución
El objeto que tiene un estado interesante suele denominarse suje-
to, pero, como también va a notificar a otros objetos los cambios
en su estado, le llamaremos notificador (en ocasiones también lla-
mado publicador). El resto de los objetos que quieren conocer los
cambios en el estado del notificador, se denominan suscriptores.
[email protected] (#44357)
Wondershare
361 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
362 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
363 Patrones de comportamiento / Observer PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
364 Patrones de comportamiento / Observer PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Observer permite al objeto editor
de texto notificar a otros objetos tipo servicio sobre los cam-
bios en su estado.
[email protected] (#44357)
Wondershare
365 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
366 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
367 Patrones de comportamiento / Observer PDFelement
#44357
28
29 // Los métodos de la lógica de negocio pueden notificar los
30 // cambios a los suscriptores.
31 method openFile(path) is
32 this
this.file = new File(path)
33 events.notify("open", file.name)
34
35 method saveFile() is
36 file.write()
37 events.notify("save", file.name)
38
39 // ...
40
41
42 // Aquí está la interfaz suscriptora. Si tu lenguaje de
43 // programación soporta tipos funcionales, puedes sustituir toda
44 // la jerarquía suscriptora por un grupo de funciones.
45
46
47 interface EventListener is
48 method update(filename)
49
50 // Los suscriptores concretos reaccionan a las actualizaciones
51 // emitidas por el notificador al que están unidos.
52 class LoggingListener implements EventListener is
53 private field log: File
54 private field message
55
56 constructor LoggingListener(log_filename, message) is
57 this
this.log = new File(log_filename)
58 this
this.message = message
59
[email protected] (#44357)
Wondershare
368 Patrones de comportamiento / Observer PDFelement
#44357
60 method update(filename) is
61 log.write(replace('%s',filename,message))
62
63 class EmailAlertsListener implements EventListener is
64 private field email: string
65
66 constructor EmailAlertsListener(email, message) is
67 this
this.email = email
68 this
this.message = message
69
70 method update(filename) is
71 system.email(email, replace('%s',filename,message))
72
73
74 // Una aplicación puede configurar notificadores y suscriptores
75 // durante el tiempo de ejecución.
76 class Application is
77 method config() is
78 editor = new Editor()
79
80 logger = new LoggingListener(
81 "/path/to/log.txt",
82 "Someone has opened the file: %s")
83 editor.events.subscribe("open", logger)
84
85 emailAlerts = new EmailAlertsListener(
86 "[email protected]",
87 "Someone has changed the file: %s")
88 editor.events.subscribe("save", emailAlerts)
[email protected] (#44357)
Wondershare
369 Patrones de comportamiento / Observer PDFelement
#44357
Aplicabilidad
Utiliza el patrón Observer cuando los cambios en el estado de
un objeto puedan necesitar cambiar otros objetos y el grupo
de objetos sea desconocido de antemano o cambie dinámica-
mente.
[email protected] (#44357)
Wondershare
370 Patrones de comportamiento / Observer PDFelement
#44357
Cómo implementarlo
1. Repasa tu lógica de negocio e intenta dividirla en dos partes:
la funcionalidad central, independiente del resto de código,
actuará como notificador; el resto se convertirá en un grupo de
clases suscriptoras.
[email protected] (#44357)
Wondershare
371 Patrones de comportamiento / Observer PDFelement
#44357
Pros y contras
Principio de abierto/cerrado. Puedes introducir nuevas clases
suscriptoras sin tener que cambiar el código de la notificadora
(y viceversa si hay una interfaz notificadora).
Puedes establecer relaciones entre objetos durante el tiempo
de ejecución.
[email protected] (#44357)
Wondershare
372 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
373 Patrones de comportamiento / Observer PDFelement
#44357
[email protected] (#44357)
Wondershare
374 Patrones de comportamiento / State PDFelement
#44357
STATE
También llamado: Estado
[email protected] (#44357)
Wondershare
375 Patrones de comportamiento / State PDFelement
#44357
Problema
El patrón State está estrechamente relacionado con el conce-
pto de la Máquina de estados finitos.
[email protected] (#44357)
Wondershare
376 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
377 Patrones de comportamiento / State PDFelement
#44357
1 class Document is
2 field state: string
3 // ...
4 method publish() is
5 switch (state)
6 "draft":
7 state = "moderation"
8 break
9 "moderation":
10 if (currentUser.role == 'admin')
11 state = "published"
12 break
13 "published":
14 // No hacer nada.
15 break
16 // ...
[email protected] (#44357)
Wondershare
378 Patrones de comportamiento / State PDFelement
#44357
Solución
El patrón State sugiere que crees nuevas clases para todos los
estados posibles de un objeto y extraigas todos los comporta-
mientos específicos del estado para colocarlos dentro de esas
clases.
[email protected] (#44357)
Wondershare
379 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
380 Patrones de comportamiento / State PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
381 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
382 Patrones de comportamiento / State PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón State permite a los mismos contro-
les del reproductor de medios comportarse de forma diferente,
dependiendo del estado actual de reproducción.
[email protected] (#44357)
Wondershare
383 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
384 Patrones de comportamiento / State PDFelement
#44357
33 method clickNext() is
34 state.clickNext()
35 method clickPrevious() is
36 state.clickPrevious()
37
38 // Un estado puede invocar algunos métodos del servicio en
39 // el contexto.
40 method startPlayback() is
41 // ...
42 method stopPlayback() is
43 // ...
44 method nextSong() is
45 // ...
46 method previousSong() is
47 // ...
48 method fastForward(time) is
49 // ...
50 method rewind(time) is
51 // ...
52
53
54 // La clase estado base declara métodos que todos los estados
55 // concretos deben implementar, y también proporciona una
56 // referencia inversa al objeto de contexto asociado con el
57 // estado. Los estados pueden utilizar la referencia inversa
58 // para dirigir el contexto a otro estado.
59 abstract class State is
60 protected field player: AudioPlayer
61
62 // El contexto se pasa a sí mismo a través del constructor
63 // del estado. Esto puede ayudar al estado a extraer
64 // información de contexto útil si la necesita.
[email protected] (#44357)
Wondershare
385 Patrones de comportamiento / State PDFelement
#44357
65 constructor State(player) is
66 this
this.player = player
67
68 abstract method clickLock()
69 abstract method clickPlay()
70 abstract method clickNext()
71 abstract method clickPrevious()
72
73
74 // Los estados concretos implementan varios comportamientos
75 // asociados a un estado del contexto.
76 class LockedState extends State is
77
78 // Cuando desbloqueas a un jugador bloqueado, puede asumir
79 // uno de dos estados.
80 method clickLock() is
81 if (player.playing)
82 player.changeState(new
new PlayingState(player))
83 else
84 player.changeState(new
new ReadyState(player))
85
86 method clickPlay() is
87 // Bloqueado, no hace nada.
88
89 method clickNext() is
90 // Bloqueado, no hace nada.
91
92 method clickPrevious() is
93 // Bloqueado, no hace nada.
94
95 // También pueden disparar transiciones de estado en el
96 // contexto.
[email protected] (#44357)
Wondershare
386 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
387 Patrones de comportamiento / State PDFelement
#44357
129 else
130 player.rewind(5)
Aplicabilidad
Utiliza el patrón State cuando tengas un objeto que se compo-
rta de forma diferente dependiendo de su estado actual, el nú-
mero de estados sea enorme y el código específico del estado
cambie con frecuencia.
[email protected] (#44357)
Wondershare
388 Patrones de comportamiento / State PDFelement
#44357
Cómo implementarlo
1. Decide qué clase actuará como contexto. Puede ser una clase
existente que ya tiene el código dependiente del estado, o una
nueva clase, si el código específico del estado está distribuido
a lo largo de varias clases.
[email protected] (#44357)
Wondershare
389 Patrones de comportamiento / State PDFelement
#44357
Pros y contras
Principio de responsabilidad única. Organiza el código relacio-
nado con estados particulares en clases separadas.
Principio de abierto/cerrado. Introduce nuevos estados sin cam-
biar clases de estado existentes o la clase contexto.
[email protected] (#44357)
Wondershare
390 Patrones de comportamiento / State PDFelement
#44357
[email protected] (#44357)
Wondershare
391 Patrones de comportamiento / Strategy PDFelement
#44357
STRATEGY
También llamado: Estrategia
[email protected] (#44357)
Wondershare
392 Patrones de comportamiento / Strategy PDFelement
#44357
Problema
Un día decidiste crear una aplicación de navegación para via-
jeros ocasionales. La aplicación giraba alrededor de un bonito
mapa que ayudaba a los usuarios a orientarse rápidamente en
cualquier ciudad.
[email protected] (#44357)
Wondershare
393 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
394 Patrones de comportamiento / Strategy PDFelement
#44357
Solución
El patrón Strategy sugiere que tomes esa clase que hace algo
específico de muchas formas diferentes y extraigas todos esos
algoritmos para colocarlos en clases separadas llamadas estra-
tegias.
[email protected] (#44357)
Wondershare
395 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
396 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
397 Patrones de comportamiento / Strategy PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
398 Patrones de comportamiento / Strategy PDFelement
#44357
Pseudocódigo
En este ejemplo, el contexto utiliza varias estrategias para eje-
cutar diversas operaciones aritméticas.
[email protected] (#44357)
Wondershare
399 Patrones de comportamiento / Strategy PDFelement
#44357
16 method execute(a, b) is
17 return a - b
18
19 class ConcreteStrategyMultiply implements Strategy is
20 method execute(a, b) is
21 return a * b
22
23 // El contexto define la interfaz de interés para los clientes.
24 class Context is
25 // El contexto mantiene una referencia a uno de los objetos
26 // de estrategia. El contexto no conoce la clase concreta de
27 // una estrategia. Debe trabajar con todas las estrategias a
28 // través de la interfaz estrategia.
29 private strategy: Strategy
30
31 // Normalmente, el contexto acepta una estrategia a través
32 // del constructor y también proporciona un setter
33 // (modificador) para poder cambiar la estrategia durante el
34 // tiempo de ejecución.
35 method setStrategy(Strategy strategy) is
36 this
this.strategy = strategy
37
38 // El contexto delega parte del trabajo al objeto de
39 // estrategia en lugar de implementar varias versiones del
40 // algoritmo por su cuenta.
41 method executeStrategy(int a, int b) is
42 return strategy.execute(a, b)
43
44
45 // El código cliente elige una estrategia concreta y la pasa al
46 // contexto. El cliente debe conocer las diferencias entre
47 // estrategias para elegir la mejor opción.
[email protected] (#44357)
Wondershare
400 Patrones de comportamiento / Strategy PDFelement
#44357
48 class ExampleApplication is
49 method main() is
50 Create context object.
51
52 Read first number.
53 Read last number.
54 Read the desired action from user input.
55
56 if (action == addition) then
57 context.setStrategy(new
new ConcreteStrategyAdd())
58
59 if (action == subtraction) then
60 context.setStrategy(new
new ConcreteStrategySubtract())
61
62 if (action == multiplication) then
63 context.setStrategy(new
new ConcreteStrategyMultiply())
64
65 result = context.executeStrategy(First number, Second number)
66
67 Print result.
Aplicabilidad
Utiliza el patrón Strategy cuando quieras utiliza distintas va-
riantes de un algoritmo dentro de un objeto y poder cambiar
de un algoritmo a otro durante el tiempo de ejecución.
[email protected] (#44357)
Wondershare
401 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
402 Patrones de comportamiento / Strategy PDFelement
#44357
Cómo implementarlo
1. En la clase contexto, identifica un algoritmo que tienda a sufrir
cambios frecuentes. También puede ser un enorme condicio-
nal que seleccione y ejecute una variante del mismo algoritmo
durante el tiempo de ejecución.
[email protected] (#44357)
Wondershare
403 Patrones de comportamiento / Strategy PDFelement
#44357
Pros y contras
Puedes intercambiar algoritmos usados dentro de un objeto
durante el tiempo de ejecución.
Puedes aislar los detalles de implementación de un algoritmo
del código que lo utiliza.
Puedes sustituir la herencia por composición.
[email protected] (#44357)
Wondershare
404 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
405 Patrones de comportamiento / Strategy PDFelement
#44357
[email protected] (#44357)
Wondershare
406 Patrones de comportamiento / Template Method PDFelement
#44357
TEMPLATE METHOD
También llamado: Método plantilla
[email protected] (#44357)
Wondershare
407 Patrones de comportamiento / Template Method PDFelement
#44357
Problema
Imagina que estás creando una aplicación de minería de datos
que analiza documentos corporativos. Los usuarios suben a la
aplicación documentos en varios formatos (PDF, DOC, CSV) y
ésta intenta extraer la información relevante de estos docume-
ntos en un formato uniforme.
[email protected] (#44357)
Wondershare
408 Patrones de comportamiento / Template Method PDFelement
#44357
Solución
El patrón Template Method sugiere que dividas un algoritmo
en una serie de pasos, conviertas estos pasos en métodos y
coloques una serie de llamadas a esos métodos dentro de un
único método plantilla. Los pasos pueden ser abstractos , o
contar con una implementación por defecto. Para utilizar el al-
goritmo, el cliente debe aportar su propia subclase, impleme-
ntar todos los pasos abstractos y sobrescribir algunos de los
opcionales si es necesario (pero no el propio método plantilla).
[email protected] (#44357)
Wondershare
409 Patrones de comportamiento / Template Method PDFelement
#44357
[email protected] (#44357)
Wondershare
410 Patrones de comportamiento / Template Method PDFelement
#44357
[email protected] (#44357)
Wondershare
411 Patrones de comportamiento / Template Method PDFelement
#44357
[email protected] (#44357)
Wondershare
412 Patrones de comportamiento / Template Method PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
413 Patrones de comportamiento / Template Method PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Template Method proporciona un
“esqueleto” para varias ramas de inteligencia artificial (IA) en
un sencillo videojuego de estrategia.
[email protected] (#44357)
Wondershare
414 Patrones de comportamiento / Template Method PDFelement
#44357
[email protected] (#44357)
Wondershare
415 Patrones de comportamiento / Template Method PDFelement
#44357
29 else
30 sendWarriors(enemy.position)
31
32 abstract method sendScouts(position)
33 abstract method sendWarriors(position)
34
35 // Las clases concretas tienen que implementar todas las
36 // operaciones abstractas de la clase base, pero no deben
37 // sobrescribir el propio método plantilla.
38 class OrcsAI extends GameAI is
39 method buildStructures() is
40 if (there are some resources) then
41 // Construye granjas, después cuarteles y después
42 // fortaleza.
43
44 method buildUnits() is
45 if (there are plenty of resources) then
46 if (there are no scouts)
47 // Crea peón y añádelo al grupo de exploradores.
48 else
49 // Crea soldado, añádelo al grupo de guerreros.
50
51 // ...
52
53 method sendScouts(position) is
54 if (scouts.length > 0) then
55 // Envía exploradores a posición.
56
57 method sendWarriors(position) is
58 if (warriors.length > 5) then
59 // Envía guerreros a posición.
60
[email protected] (#44357)
Wondershare
416 Patrones de comportamiento / Template Method PDFelement
#44357
Aplicabilidad
Utiliza el patrón Template Method cuando quieras permitir a
tus clientes que extiendan únicamente pasos particulares de
un algoritmo, pero no todo el algoritmo o su estructura.
[email protected] (#44357)
Wondershare
417 Patrones de comportamiento / Template Method PDFelement
#44357
Cómo implementarlo
1. Analiza el algoritmo objetivo para ver si puedes dividirlo en
pasos. Considera qué pasos son comunes a todas las subclases
y cuáles siempre serán únicos.
[email protected] (#44357)
Wondershare
418 Patrones de comportamiento / Template Method PDFelement
#44357
5. Para cada variación del algoritmo, crea una nueva subclase co-
ncreta. Ésta debe implementar todos los pasos abstractos, pero
también puede sobrescribir algunos de los opcionales.
Pros y contras
Puedes permitir a los clientes que sobrescriban tan solo cier-
tas partes de un algoritmo grande, para que les afecten menos
los cambios que tienen lugar en otras partes del algoritmo.
Puedes colocar el código duplicado dentro de una superclase.
[email protected] (#44357)
Wondershare
419 Patrones de comportamiento / Template Method PDFelement
#44357
[email protected] (#44357)
Wondershare
420 Patrones de comportamiento / Visitor PDFelement
#44357
VISITOR
También llamado: Visitante
[email protected] (#44357)
Wondershare
421 Patrones de comportamiento / Visitor PDFelement
#44357
Problema
Imagina que tu equipo desarrolla una aplicación que funcio-
na con información geográfica estructurada como un enorme
grafo. Cada nodo del grafo puede representar una entidad co-
mpleja, como una ciudad, pero también cosas más específicas,
como industrias, áreas turísticas, etc. Los nodos están conec-
tados con otros si hay un camino entre los objetos reales que
representan. Técnicamente, cada tipo de nodo está represen-
tado por su propia clase, mientras que cada nodo específico es
un objeto.
[email protected] (#44357)
Wondershare
422 Patrones de comportamiento / Visitor PDFelement
#44357
Había otra razón para el rechazo. Era muy probable que, una
vez que se implementara esta función, alguien del departame-
nto de marketing te pidiera que incluyeras la capacidad de ex-
portar a otros formatos, o te pidiera alguna otra cosa extraña.
Esto te forzaría a cambiar de nuevo esas preciadas y frágiles
clases.
[email protected] (#44357)
Wondershare
423 Patrones de comportamiento / Visitor PDFelement
#44357
Solución
El patrón Visitor sugiere que coloques el nuevo comportamie-
nto en una clase separada llamada visitante, en lugar de in-
tentar integrarlo dentro de clases existentes. El objeto que
originalmente tenía que realizar el comportamiento se pasa
ahora a uno de los métodos del visitante como argumento, de
modo que el método accede a toda la información necesaria
contenida dentro del objeto.
[email protected] (#44357)
Wondershare
424 Patrones de comportamiento / Visitor PDFelement
#44357
[email protected] (#44357)
Wondershare
425 Patrones de comportamiento / Visitor PDFelement
#44357
1 // Código cliente
2 foreach (Node node in graph)
3 node.accept(exportVisitor)
4
5 // Ciudad
6 class City is
7 method accept(Visitor v) is
8 v.doForCity(this
this)
9 // ...
10
11 // Industria
12 class Industry is
13 method accept(Visitor v) is
14 v.doForIndustry(this
this)
15 // ...
[email protected] (#44357)
Wondershare
426 Patrones de comportamiento / Visitor PDFelement
#44357
[email protected] (#44357)
Wondershare
427 Patrones de comportamiento / Visitor PDFelement
#44357
Estructura
[email protected] (#44357)
Wondershare
428 Patrones de comportamiento / Visitor PDFelement
#44357
Pseudocódigo
En este ejemplo, el patrón Visitor añade soporte de exporta-
ción XML a la jerarquía de clases de formas geométricas.
[email protected] (#44357)
Wondershare
429 Patrones de comportamiento / Visitor PDFelement
#44357
[email protected] (#44357)
Wondershare
430 Patrones de comportamiento / Visitor PDFelement
#44357
12 // ...
13
14 // Observa que invocamos `visitDot`, que coincide con el
15 // nombre de la clase actual. De esta forma, hacemos saber
16 // al visitante la clase del elemento con el que trabaja.
17 method accept(v: Visitor) is
18 v.visitDot(this
this)
19
20 class Circle implements Shape is
21 // ...
22 method accept(v: Visitor) is
23 v.visitCircle(this
this)
24
25 class Rectangle implements Shape is
26 // ...
27 method accept(v: Visitor) is
28 v.visitRectangle(this
this)
29
30 class CompoundShape implements Shape is
31 // ...
32 method accept(v: Visitor) is
33 v.visitCompoundShape(this
this)
34
35
36 // La interfaz Visitor declara un grupo de métodos de visita que
37 // se corresponden con clases de elemento. La firma de un método
38 // de visita permite al visitante identificar la clase exacta
39 // del elemento con el que trata.
40 interface Visitor is
41 method visitDot(d: Dot)
42 method visitCircle(c: Circle)
43 method visitRectangle(r: Rectangle)
[email protected] (#44357)
Wondershare
431 Patrones de comportamiento / Visitor PDFelement
#44357
[email protected] (#44357)
Wondershare
432 Patrones de comportamiento / Visitor PDFelement
#44357
Aplicabilidad
Utiliza el patrón Visitor cuando necesites realizar una opera-
ción sobre todos los elementos de una compleja estructura de
objetos (por ejemplo, un árbol de objetos).
[email protected] (#44357)
Wondershare
433 Patrones de comportamiento / Visitor PDFelement
#44357
Cómo implementarlo
1. Declara la interfaz visitante con un grupo de métodos “visita-
ntes”, uno por cada clase de elemento concreto existente en el
programa.
[email protected] (#44357)
Wondershare
434 Patrones de comportamiento / Visitor PDFelement
#44357
Pros y contras
Principio de abierto/cerrado. Puedes introducir un nuevo com-
portamiento que puede funcionar con objetos de clases dife-
rentes sin cambiar esas clases.
Principio de responsabilidad única. Puedes tomar varias versio-
nes del mismo comportamiento y ponerlas en la misma clase.
Un objeto visitante puede acumular cierta información útil
mientras trabaja con varios objetos. Esto puede resultar útil
[email protected] (#44357)
Wondershare
435 Patrones de comportamiento / Visitor PDFelement
#44357
Debes actualizar todos los visitantes cada vez que una clase se
añada o elimine de la jerarquía de elementos.
Los visitantes pueden carecer del acceso necesario a los cam-
pos y métodos privados de los elementos con los que se supo-
ne que deben trabajar.
• Puedes utilizar Visitor junto con Iterator para recorrer una es-
tructura de datos compleja y ejecutar alguna operación sobre
sus elementos, incluso aunque todos tengan clases distintas.
[email protected] (#44357)
Wondershare
PDFelement
#44357
Conclusión
¡Felicidades! ¡Has llegado al final del libro!
Sin embargo, hay muchos otros patrones en el mundo. Espe-
ro que el libro se convierta en tu punto de partida para ap-
render patrones y desarrollar superpoderes para el diseño de
programas.
[email protected] (#44357)