7/27/2019 8 Patrones
1/137
Patrones de Diseo
Tema 7
Grupo 46
111
Curso 2008/09
7/27/2019 8 Patrones
2/137
z n ro ucc n.
{ Patrones.{ Descripcin de los Patrones.
{ Ejemplo: Patrones en el MVC de Smalltalk.
{ El catlogo de patrones.z Patrones de Creacin.z Patrones Estructurales.z
Patrones de Comportamiento.onc us ones.z Bibliografa.
222
7/27/2019 8 Patrones
3/137
se o espec co para e pro ema, pero genera comopara poder adecuarse a futuros requisitos y problemas.
z Evitar el rediseo en la medida de lo posible.
z Evitar resolver cada problema partiendo de cero.
z Reutilizar soluciones que han sido tiles en el pasado.
z Patrones recurrentes de clases y comunicacin entreobjetos en muchas soluciones de diseo.
3
7/27/2019 8 Patrones
4/137
.
z ,funcionado. Se tiene experiencia sobre su uso.
zx s en en muc os om n os:{ Novelas y el cine: hroe trgico, comedia romntica, etc.{ Arte.{ Ingenieras.{ Arquitectura.
z Christo her Alexander. A Pattern Lan ua e: Towns Buildin sConstruction. 1977.
z http://www.patternlanguage.com
4
7/27/2019 8 Patrones
5/137
eu zar se os a s rac os que no nc uyan e a es
de la implementacin.
z Un patrn es una descripcin del problema y la esenciade su solucin, que se puede reutilizar en casos
distintos.
z Es una solucin adecuada a un problema comn.
soc a o a or en ac n a o e os, pero e pr nc p ogeneral es aplicable a todos los enfoques de diseosoftware.
5
7/27/2019 8 Patrones
6/137
ocumen ar a exper enc a en e se o, en
forma de un catlogo de patrones.z Categoras de patrones:
{ De creacin: implica el proceso de instanciar objetos.
{ Estructurales: composicin de objetos.
e compor am en o: u ,cooperan y distribuyen las responsabilidades paralograr sus objetivos.
6
7/27/2019 8 Patrones
7/137
Patrones de DiseoEstructura de un patrn
om re e pa r n.
{ Describe el problema de diseo, junto con sus soluciones y
consecuencias.oca u ar o e se o.
z Problema.
{ Describe cundo aplicar el patrn.
{ Explica el problema y su contexto.z Solucin.
{ Elementos ue forman el diseo relaciones res onsabilidades.{ No un diseo concreto, sino una plantilla que puede aplicarse en
muchas situaciones distintas.
.{ Resultados, ventajas e inconvenientes de aplicar el patrn.{ P.ej.: relacin entre eficiencia en espacio y tiempo; cuestiones de
7
, .
7/27/2019 8 Patrones
8/137
Patrones de DiseoEjemplo: MVC de Smalltalk
zModelo/Vista/Controlador.
A
C
D
10
20
30
A B C D
X 60 20 15 5
Y 40 25 15 20B
0A B C DZ 10 10 20 60
ModeloA: 40%B: 25%
8
:
D: 20%
7/27/2019 8 Patrones
9/137
Patrones de DiseoEjemplo: MVC de Smalltalk
eparar os o e os con os a os mo e o , susvisualizaciones (vistas) y el modo en que la interfazreacciona ante la entrada al usuario controlador .
z Separar estos componentes, para aumentar la
flexibilidad y reutilizacin.
z Desacoplar vistas de modelos, mediante un protocolo desubscripcin/notificacin.
z Cada vez que cambian los datos del modelo, avisar alas vistas ue de enden de l. Estas se actualizan.
9
7/27/2019 8 Patrones
10/137
Patrones de DiseoEjemplo: MVC de Smalltalk
,objetos).
z Las vistas se pueden anidar: Vistas compuestas ysimples.
.
z La relacin entre la vista y el controlador: patrnra egy un o e o que represen a un a gor mo .
{ Factory Method: especifica la clase controlador predeterminada
para una vista.
10
.
7/27/2019 8 Patrones
11/137
Propsito
Creacin Estructurales De Comportamiento
Clase Factory Method Adapter (de clases) Interpreter..
Objeto Abstract Factory Adapter (de objetos). Chain of Responsibility.bit
o
Builder
Prototype
Singleton
Bridge.
Composite.
Decorator.
Command.
Iterator.
Mediator.Facade.
Flyweight.
Memento.
Observer.
11Strategy.Visitor.
7/27/2019 8 Patrones
12/137
El catlogo
de patronesRelaciones entre
los patrones.
12
7/27/2019 8 Patrones
13/137
.z
Patrones de Creacin..{Abstract Factory.
{Factory Method.
z Patrones Estructurales.z Patrones de Comportamiento.
onc us ones.z Bibliografa.
131313
7/27/2019 8 Patrones
14/137
s raen e proceso e ns anc ac n
z Ayudan a que el sistema sea independiente de,objetos.
z
{ qu se crea{ quin lo crea{ cmo se crea{ cundo se crea
{ estticamente (compile-time){ dinmicamente run-time
14
7/27/2019 8 Patrones
15/137
n enc n.{ Asegurar que una clase tiene una nica instancia y proporciona un
punto de acceso global a dicha instancia.z Motivacin.
{ Hay veces que es importante asegurar que una clase tenga una,
z Un gestor de ventanasz Una nica cola de impresinz Un nico sistema de ficherosz Un nico fichero de log, o un nico repositorio.
{Cmo asegurarlo? una variable global hace el objeto, .
{Responsabilidad de la clase misma: actuar sobre elmensaje de creacin de instancias
15
7/27/2019 8 Patrones
16/137
z Aplicabilidad.
{
Cuando debe haber una sola instancia, y debe ser accesible a los.
{ Cuando la nica instancia debe ser extensible mediantesubclasificacin, y los clientes deben ser capaces de usar una
.
z Estructura.
Singleton
static Singleton uniqueInstance
singletonDatastatic Singleton Instance ()SingletonOperation ()GetSingletonData ()
return uniqueInstance
16
7/27/2019 8 Patrones
17/137
z Participantes:
{ Singleton:z Define una operacin de clase, llamada Instance que deja a los clientes
acceder a la nica instancia.z Puede ser responsable de crear su nica instancia.
z Colaboraciones:
{ Los clientes acceden a la instancia de un Singleton a travs de laoperacin Instance.
z Consecuencias:
{ Acceso controlado a la nica instancia.{ Espacio de nombre reducido. Mejora sobre el uso de variables
globales.
{ Permite el refinamiento de operaciones y la representacin. Se puedesubclasificar de la clase Singleton y configurar la aplicacin con unainstancia de esta clase.
{ Fcil modificacin para permitir un nmero variable de instancias.
17
{ Ms flexible que las operaciones de clase.
7/27/2019 8 Patrones
18/137
class Singleton {private:
static Singleton* _instance;void otherOperations();
protected:Singleton();
public:static Singleton* getInstance();
};
Singleton* Singleton::_instance = 0;
Singleton* Singleton::getInstance() {if (_instance == 0 )
18
_
return _instance;}
7/27/2019 8 Patrones
19/137
#include "stdafx.h"#include using namespace std;
class Maze{int x, y;
public:Maze(int x, int y) : x(x), y(y) {}
};
class MazeFactory {public:
static MazeFactory* Instance();// existing interface goes hereMaze * createMaze(int x, int y) { return new Maze(x, y); };
pro ec e :
MazeFactory() {};private:
static MazeFactory* _instance;;
MazeFactory* MazeFactory::_instance = 0;
aze ac ory aze ac ory:: ns anceif (_instance == 0) _instance = new MazeFactory;return _instance;
}
19void main(){Maze * m = MazeFactory::Instance()->createMaze(10,10);}
7/27/2019 8 Patrones
20/137
Singletonz Implementacin:
{ Creacin de una subclase de singleton.
e erm nar qu s ng e on queremos usar en a operac n ns ance .
{ Registro de objetos singleton.
class Singleton {public:
static void Register(const char* name, Singleton*);*
protected:static Singleton* Lookup(const char* name);private:
static Singleton* _instance;static List* _registry;
};
ng e on ng e on:: ns anceif (_instance == 0) {
const char* singletonName =getenv("SINGLETON");// user or environment su lies this at startu
20
_instance = Lookup(singletonName); // Lookup returns 0 if there's no such singleton
}return _instance; }
7/27/2019 8 Patrones
21/137
z Dnde se registra la clase?
{ Una posibilidad es en el constructor.MySingleton::MySingleton() {// ...Singleton::Register("MySingleton", this);
{Entonces hay que instanciar la clase!}
{Se puede crear una instancia global:static MySingleton theSingleton;
21
7/27/2019 8 Patrones
22/137
Sin letonEjemplo
*class MazeFactory {public:
static MazeFactory* Instance();// existing interface goes here
if (_instance == 0) {const char* mazeStyle = getenv("MAZESTYLE");
if (strcmp(mazeStyle, "bombed") == 0)protected:
MazeFactory();private:
*
_instance = new BombedMazeFactory;} else if (strcmp(mazeStyle, "enchanted") == 0)_instance = new EnchantedMazeFactory;
// ... other possible subclasses _
};
MazeFactory* MazeFactory::_instance = 0;
} else_instance = new MazeFactory;return _instance;
22
7/27/2019 8 Patrones
23/137
rop s o .{Proporciona una interfaz para crear familias de objetos
relacionados o que dependen entre s, sin especificar susc ases concretas.
z Tambin Conocido Como..
zMotivacin.{ Ej.: un framework para la construccin de interfaces de usuario
que permita varios look and feel (ej.: Motif y PresentationManager).z
Una clase abstracta WidgetFactory con la interfaz para crear.zUna clase abstracta para cada tipo de widget. Subclases
concretas que implementan cada widget concreto.
23
,
and feel concreto.
7/27/2019 8 Patrones
24/137
z Motivacin.
WidgetFactory
CreateScrollBar()
CreateWindow()
Client
Window
Productos
MotifWindowPMWindowFamilias
CreateScrollBar()CreateWindow()
CreateScrollBar()CreateWindow()
ScrollBar
MotifScrollBarPMScrollBar
24
7/27/2019 8 Patrones
25/137
zAplicabilidad. Usar este patrn cuando:
{un sistema que deba ser independiente de cmo secrean, componen y representan sus pro uctos.
{un sistema que deba ser configurado con una familia de.
{una familia de objetos producto relacionados que est,
hacer cumplir esta restriccin.
{se quiere proporcionar una biblioteca de clasesproductos, y slo se quiere revelar sus interfaces, no suimplementacin.
25
7/27/2019 8 Patrones
26/137
zEstructura:
AbstractFactory
createProductA
Client
ProductoscreateProductB () AbstractProductA
Familias
ConcreteFactory1
createProductA ()
ConcreteFactory2
createProductA ()AbstractProductB
ProductA1ProductA2
ProductB1ProductB2
26
7/27/2019 8 Patrones
27/137
z Partici antes:
{AbstractFactory. Declara una interfaz para operaciones quecrean objetos producto abstractos.
{ ConcreteFactor . Im lementa las o eraciones ara crear ob etosproducto concretos.
{AbstractProduct. Declara una interfaz para un tipo de objetoproducto.
{ ConcreteProduct. Define un objeto producto para que sea creadopor la fbrica correspondiente.
{ Client. Slo usa interfaces declaradas por las clasess rac ac ory y s rac ro uc .
z Colaboraciones.
{ Normalmente slo se crea una nica instancia de una claseConcreteFactory en tiempo de ejecucin. Esta fbrica concretacrea objetos producto que tienen una determinadaimplementacin.
27
s rac ac ory e ega a creac n e o e os pro uc o en su
subclase ConcreteFactory.
7/27/2019 8 Patrones
28/137
z onsecuenc as.
{Asla las clases concretas. Ayuda a controlarlas clases de objetos que crea una aplicacin.Asla a los clientes de las clases de
.{Facilita el reemplazo de familias de productos.
romueve a cons s enc a en re pro uc os quela aplicacin use objetos de una sola familia a
.{Es difcil aadir un nuevo producto.
28
7/27/2019 8 Patrones
29/137
r F rEjemplo
Ejemplo: aplicacin para construir un coche a partir
de unas partes (motor, chasis, ...) o os os componen es e a m sma marca am a hay mltiples marcas (Ford, Toyota, Opel, ...) es res onsabilidad del cliente ensamblar las iezas
Car
ToyotaCarFordCar PorscheCar CarPart
CarBodyCarEngine
29ToyotaBodyFordBody PorscheBodyToyotaEngineFordEngine PorscheEngine
7/27/2019 8 Patrones
30/137
r F rEjemplo (ii)
En un mtodo del cliente:
CrearCoche (string marca) {
if (marca == ford)FordCar coche = new FordCar ()
El cdigo del clientedecide qu clase de
else if (marca == toyota)
ToyotaCar coche = new ToyotaCar ()else ;
y qu subpartesinstanciar (mal). Puede
if (marca == ford)FordEngine motor = new FordEngine ()
else if (marca == toyota)
ToyotaEngine motor = new ToyotaEngine ()
cometerse el error deensamblar partes de
else ;
coche.add (motor);...
.
30return coche;
}
7/27/2019 8 Patrones
31/137
r F rEjemplo (iii)
CarPartFactory
makeCar ()
makeBod
Client
CarBod
Productos
makeEngine ()
ToyotaBodyFordBodyFamilias
ToyotaFactory FordFactory CarEngine
makeBody ()makeEngine ()
makeBody ()makeEngine () ToyotaEngineFordEngine
Car
31
ToyotaCarFordCar
7/27/2019 8 Patrones
32/137
r F rEjemplo (iv)
Utilizando el patrn, ste fuerza a que todos los productos sean de lamisma familia, una vez establecida sta por el cliente.
El patrn permite separar la eleccin de la familia (la marca delcoche) del proceso de instanciar las partes.
En el cliente:
Car hacerCoche () {
Car coche=familia.makeCar();coche.addEngine (familia.makeEngine());coche.addBody (familia.makeBody ());...
32
re urn coc e;
}
7/27/2019 8 Patrones
33/137
r F rEjemplo (v)
. Cmo se instancia f ami l i a?
class CrearCoche {CarPartFactor * familia
Car hacerCoche () {Car coche=familia->makeCar();coche.addEn ine familia->makeEn ine
//presenta por pantalla la seleccinclass CrearCocheGUI : public CFrameWnd {//.
coche.addBody (familia->makeBody ());
...return coche;
vo n u on c e
string familiasel;CrearCoche assembler;Car coche;
static CrearCoche using (CarPartFactory * f) {CrearCoche l;
l.factor f ;
if (familiasel == ford)
assembler=CrearCoche::using (new FordFactory())else if (familiasel == toyota)
return l;}
void factor CarPartFactor * f
assem er= rear oc e::us ng new oyo a ac oryelse ;
coche = assembler.hacerCoche();
33
familia=f;
}}
}
7/27/2019 8 Patrones
34/137
r F rOtro Ejemplo: Laberinto
MazeFactory
+MakeMaze(): Maze
MazeGame
+CreateMaze(MazeFactory): Maze+MakeWall(): Wall
+MakeRoom(int n): Room
+MakeDoor(Room r1, Room r2): Door
Maze Wall RoomEnchantedMazeFactory
+MakeRoom(int n): EnchantedRoom+MakeDoor(Room r1, Room r2):
DoorNeedingSpell
EnchantedRoom
BombedWall
DoorBombedMazeFactory
RoomWithABomb
34DoorNeedingSpell
+MakeRoom(int n): RoomWithABomb
+MakeWall(): BombedWall
7/27/2019 8 Patrones
35/137
r F rOtro Ejemplo: Laberinto
class MazeFactory {public:
MazeFactory();v r ua aze a e aze cons
{ return new Maze; }virtual Wall* MakeWall() constreturn new Wall
virtual Room* MakeRoom(int n) const{ return new Room(n); }virtual Door* MakeDoor(Room* r1, Room* r2) const
re urn new oor r , r ;};
35
7/27/2019 8 Patrones
36/137
r F rOtro Ejemplo
Maze* MazeGame::CreateMaze (MazeFactory& factory) {Maze* aMaze = factory.MakeMaze();Room* r1 = factor .MakeRoom 1Room* r2 = factory.MakeRoom(2);Door* aDoor = factory.MakeDoor(r1, r2);aMaze->AddRoom(r1);a aze-> oom r ;
r1->SetSide(North, factory.MakeWall());r1->SetSide(East, aDoor);r1->SetSide South factor .MakeWallr1->SetSide(West, factory.MakeWall());r2->SetSide(North, factory.MakeWall());r2->SetSide(East, factory.MakeWall());r - e e ou , ac ory. a e a ;r2->SetSide(West, aDoor);return aMaze;
36
7/27/2019 8 Patrones
37/137
r F rOtro Ejemplo
class EnchantedMazeFactory : public MazeFactory {public:
EnchantedMazeFactory();*{ return new EnchantedRoom(n, CastSpell()); }virtual Door* MakeDoor(Room* r1, Room* r2) const
return new DoorNeedin S ell r1, r2 ;}
protected:Spell* CastSpell() const;
// Make it possible to have rooms with bombs
*
MazeGame game;
BombedMazeFactor factorreturn new BombedWall;
}Room* BombedMazeFactory::MakeRoom(int n) const {
game.CreateMaze(factory);
37
return new oom t om n ;
}
7/27/2019 8 Patrones
38/137
rop s o .{Define una interfaz para crear un objeto, pero deja que
sean las subclases uienes decidan u clase instanciar.Permite que una clase delegue en sus subclases lacreacin de objetos.
.
{Virtual Constructor.zMotivacin.
{Ej.: un framework que pueda presentar distintos tipos dedocumentos (similar a MFCs).
zDos abstracciones clave: a licacin documento ambasclases abstractas). Hay que subclasificarlas.zLa clase aplicacin no sabe qu subclase documento
instanciar.
38
7/27/2019 8 Patrones
39/137
zMotivacin.
Se le llama factory method (mtodo
de fabricacin)
Documento
+Abrir
Aplicacion
+
docs1..*
Documento * doc = CrearDocumento()
+Cerrar()+Guardar()+Deshacer()
+NuevoDocumento()+AbrirDocumento()
ocs.pus _ ac oc
doc->Abrir()
MiDocumentoMiAplicacion
return new MiDocumento+ rear ocumen o
39
7/27/2019 8 Patrones
40/137
z p ca a . sar este patr n cuan o:
{ Una clase no puede prever la clase de los objetos que tiene que crear.
crean.
{ Las clases delegan la responsabilidad en una de entre varias clases,
delega.z Estructura.
+FactoryMethod()
+
//product = factoryMethod()
//ro uc
40
oncre e ro uc oncre e rea or
+FactoryMethod() return new ConcreteProduct
7/27/2019 8 Patrones
41/137
ar c pan es.{ Product (Documento). Define la interfaz de los objetos que crea
el factory method.{ ConcreteProduct (MiDocumento). Implementa la interfaz del
producto.. .
dar una implementacin por defecto del factory method, quedevuelve un objeto de una clase por defecto..
method para devolver una instancia de ConcreteProduct.
z Colaboraciones.{ El creatorse apoya en sus subclases para definir el mtodo de
fabricacin de manera que ste devuelva una instancia delConcreteProduct adecuado.
41
7/27/2019 8 Patrones
42/137
.
{Los mtodos de fabricacin eliminan la necesidad de
li ar clases es ecficas de la a licacin a nuestrocdigo.
,
funcionar con cualquier clase ConcreteProductdefinida por el usuario.
{Proporciona enganches para las subclases. Crear
que hacerlos directamente.
42
ac ory me o es un oo me o para que as
subclases den una versin extendida del cdigo.
7/27/2019 8 Patrones
43/137
zConsecuencias.
gure an pu a or
+DownClick()+Dra
+CreateManipulator()
+UpClick()
LineManipulator
+DownClick()
TextManipulator
+DownClick()
LineFigure
TextFigure
+UpClick() +UpClick()
43
7/27/2019 8 Patrones
44/137
z mp emen ac n.
{Dos variantes principales:z Cuando la clase Creator es abstracta y noproporciona implementacin para el mtodo de
.
zCuando la clase Creator es concreta y proporcionauna implementacin predeterminada para el mtodode fabricacin.
{Mtodos de fabricacin parametrizados:z ue os ac ory me o s creen var os pos e
producto. El mtodo recibe un parmetro queidentifica el ti o de ob eto a crear.
44
7/27/2019 8 Patrones
45/137
z Implementacin.
class Creatorpublic:
Product* GetProduct();protected:
virtual Product* CreateProduct(); // factory method
private:Product* _product;
};
Product* Creator::GetProduct () {_pro uc ==
_product = CreateProduct();}
45
re urn _pro uc ;
}
7/27/2019 8 Patrones
46/137
z Implementacin. Se pueden usar plantillas para evitar
la herencia (mltiples subclases de Creator).
class Creator {public:
virtual Product* CreateProduct() = 0;// El cliente proporciona slo la clase del// producto, no necesita hacer una
// pure virtual factory method
};template
// nueva clase que herede de creator.
class MyProduct : public Product {public:
public:virtual TheProduct* CreateProduct();
};
// ...};StandardCreator myCreator;
template TheProduct*
46
return new TheProduct;
}
F M h
7/27/2019 8 Patrones
47/137
F r M hEjemplo
class MazeGame {public:
Maze* CreateMaze ;
Maze* MazeGame::CreateMaze () {Maze* aMaze = MakeMaze();
Room* r1 = MakeRoom 1// factory methods:virtual Maze* MakeMaze() const{ return new Maze; }
*
Room* r2 = MakeRoom(2);Door* theDoor = MakeDoor(r1, r2);aMaze->AddRoom(r1);
{ return new Room(n); }virtual Wall* MakeWall() const{ return new Wall; }
a aze-> oom r ;
r1->SetSide(North, MakeWall());r1->SetSide(East, theDoor);r1->SetSide South MakeWall
virtual Door* MakeDoor(Room* r1, Room* r2) const{ return new Door(r1, r2); }
};
r1->SetSide(West, MakeWall());r2->SetSide(North, MakeWall());r2->SetSide(East, MakeWall());r - e e ou , a e a ;r2->SetSide(West, theDoor);return aMaze;
47
F M h
7/27/2019 8 Patrones
48/137
F r M hEjemplo
class BombedMazeGame : public MazeGame {public:BombedMazeGame();
*{ return new BombedWall; }virtual Room* MakeRoom(int n) const{ return new RoomWithABomb(n); }
};
class EnchantedMazeGame : public MazeGame {pu c:
EnchantedMazeGame();virtual Room* MakeRoom(int n) const
return new EnchantedRoom n CastS ellvirtual Door* MakeDoor(Room* r1, Room* r2) const{ return new DoorNeedingSpell(r1, r2); }
protected:
48
pe as pe cons ;};
7/27/2019 8 Patrones
49/137
n ro ucc n.z Patrones de Creacin.
z a rones s ruc ura es.
{Com osite.
{Facade.xy.
{Adapter.z Patrones de Comportamiento.
z Conclusiones.
494949
z Bibliografa.
7/27/2019 8 Patrones
50/137
z s a ecen c mo se componen c ases y o e ospara formar estructuras mayores que
.z Los patrones de clase usan la herencia para
.
Adapter).,
componer objetos para implementar nueva
.{ Flexibilidad, ya que se puede cambiar la configuracin
en tiempo de ejecucin.
50
7/27/2019 8 Patrones
51/137
z Propsito.
{ componer objetos en estructuras arborescentes pararepresentar jerarquas parte-conjunto.
o vac n.
{Aplicaciones grficas. Manipulacin de grupos de figuras de.
Grafico
dibu agraficos*
Dibujo
dibuja ()aade (Grafico g)
Linea
dibuja ()
Rectangulo
dibuja ()
Texto
dibuja () para todo g en graficosg.dibuja ()
51
elimina (Grafico g)obtenHijo (int) aadir g a la lista de
graficos:graficos.addElement (g)
7/27/2019 8 Patrones
52/137
:Dibujo
graficos graficos graficos
graficosgraficos
:Rectangulo :Texto
7/27/2019 8 Patrones
53/137
z Aplicabilidad. Usar el patrn cuando:{ Se quieren representar jerarquas todo/parte de objetos.
{ Se quiere que los clientes ignoren la diferencia entre composiciones de
ob etos ob etos individuales. Los clientes tratarn todos los ob etos enla estructura compuesta de manera uniforme.
z Estructura.
Client Component
+ Operation()
+ Add Com onent
children
*
+ Remove(Component)
+ GetChild(int)
Composite
+ O eration forall g in children:Leaf
53
+ Add(Component)
+ Remove(Component)+ GetChild(int)
g. pera on
7/27/2019 8 Patrones
54/137
z Partici antes.{ Component (Grafico).
z Declara la interfaz de los objetos de la composicin.
z Im lementa el com ortamiento or defecto de la interfaz comn atodas las clases.z Declara las interfaces para acceder y gestionar los hijos.z (opcional) Define una interfaz para acceder al padre de un componente
en a es ruc ura recurs va y a mp emen a, s es aprop a o.
{ Leaf(Linea, Rectangulo, ).z Representa objetos hoja en la composicin. Una hoja no tiene hijos..
{ Composite (Dibujo)z Define el comportamiento de los objetos con hijos en la composicin.
.z Implementa operaciones relacionadas con los hijos de la interfaz de
Component.
54
.z Manipula objetos en la composicin a travs de la interfaz de
Component.
7/27/2019 8 Patrones
55/137
.{ Los clientes usan el interfaz de la clase Component para
interaccionar con los objetos de la estructura compuesta.e o eto es o a, entonces a pet c n se cursa rectamente.
{ Si el objeto es un Composite, entonces normalmente redirige laspeticiones a sus objetos hijo, quiz realizando operacionesadicionales antes y/o despus de la redireccin.
z Consecuencias. El patron composite:.
un cdigo cliente espera un objeto simple, se puede reemplazarpor uno compuesto.
.compuestos de manera uniforme.
{ Facilita aadir nuevos tipos de componente.
55
{ Puede hacer el diseo demasiado general. Complicado restringir
los tipos de componente de un composite.
7/27/2019 8 Patrones
56/137
mp emen ac n. gunas ec s ones:{ Referencias explcitas a los padres. En la clase component.
gestin de un componente que tiene ms de un padre es difcil.
{Maximizar la interfaz del componente..
entre seguridad y transparencia:z Declararla en la raz da transparencia. Es menos seguro porque el.
z Declararla en la clase compuesto da seguridad, pero perdemostransparencia: leafs y composites tienen interfaces distintas.
.{ Quin debe borrar los componentes?{ Cul es la mejor estructura de datos para almacenar los
56
componentes?.
m i
7/27/2019 8 Patrones
57/137
m iEjemplo
class E ui mentpublic:
virtual ~Equipment();
const char* Name() { return _name; }v r ua a ower ;virtual Currency NetPrice();virtual Currency DiscountPrice();virtual void Add E ui ment*virtual void Remove(Equipment*);
virtual Iterator* CreateIterator() {return 0;}protected:
qu pmen cons c ar ;private:
const char* _name;
57
Composite
7/27/2019 8 Patrones
58/137
p
class FloppyDisk : public Equipment {public:
Ejemplo
FloppyDisk(const char*);virtual ~FloppyDisk();virtual Watt Power();
virtual Currency DiscountPrice();
};
public:
virtual ~CompositeEquipment();virtual Watt Power ;virtual Currency NetPrice();virtual Currency DiscountPrice();virtual void Add(Equipment*);
*virtual Iterator* CreateIterator();
protected:CompositeEquipment(const char*);
58
private:
List _equipment;};
m i
7/27/2019 8 Patrones
59/137
m iEjemplo
Currency CompositeEquipment::NetPrice () {Iterator* i = CreateIterator();Currency total = 0;
-> -> ->total += i->CurrentItem()->NetPrice();
}delete i;return total;
}class Chassis : ublic Com ositeE ui mentpublic:
Chassis(const char*);virtual ~Chassis();
v r ua a ower ;virtual Currency NetPrice();virtual Currency DiscountPrice();
59
m i
7/27/2019 8 Patrones
60/137
m iEjemplo
using namespace std;
void main(){
Cabinet* cabinet = new Cabinet("PC Cabinet");* " "
cabinet->Add(chassis);Bus* bus = new Bus("MCA Bus");bus->Add(new Card("16Mbs Token Ring"));chassis->Add(bus);chassis->Add(new FloppyDisk("3.5in Floppy"));cout
7/27/2019 8 Patrones
61/137
z Propsito.{ Pro orciona una interfaz unificada ara un con unto de interfaces de un
subsistema.{ Define una interfaz de alto nivel que hace que el subsistema sea ms fcil
de usar.z Motivacin.
{ Estructurar un sistema en subsistemas ayuda a reducir su complejidad.{ Un ob etivo t ico de diseo es minimizar la comunicacin de endencias
entre subsistemas.
{ Un modo de conseguir esto es introducir un objeto fachada queproporcione una interfaz nica y simplificada a los servicios ms generalesdel subsistema.
61
7/27/2019 8 Patrones
62/137
z Motivacin.
62
7/27/2019 8 Patrones
63/137
z Aplicabilidad. Usar el patrn cuando:{ Queramos proporcionar una interfaz simple a un subsistema complejo.
Slo los clientes que necesitan ms personalizacin necesitarn ir ms
all de la fachada.{ Haya muchas dependencias entre los clientes y las clases que
implementan una abstraccin. La fachada desacopla el subsistema desus clientes otros subsistemas me ora aco lamiento ortabilidad .
{ Queramos dividir en capas nuestros subsistemas. La fachada es elpunto de entrada a cada subsistema.
s ruc ura.
63
7/27/2019 8 Patrones
64/137
.{ Facade (Compiler).
z
Sabe qu clases del subsistema son las responsables ante unape c n.z Delega las peticiones de los clientes en los objetos apropiados del
subsistema., , ,
CodeGenerator).z Implementan la funcionalidad del subsistema.z Realizan las labores encomendadas or el ob eto Facade.z No tienen referencias al objeto Facade.
z Observaciones.
objeto Facade, que las reenva a los objetos apropiados.{ Los clientes que usan la fachada no tienen que acceder
directamente a los ob etos del subsistema.
64
7/27/2019 8 Patrones
65/137
onsecuenc as.
{Oculta a los clientes los componentes del sistema, haciendo
el sistema ms fcil de usar.{Promueve acoplamiento dbil entre el subsistema y sus
clientes.
compilacin.
{No impide que las aplicaciones usen las clases del.
z Implementacin. Factores a tener en cuenta:
- .facade abstracta, con clases concretas para las diferentesimplementaciones de un subsistema.
65
.de nombres en C++.
F
7/27/2019 8 Patrones
66/137
Ejemplo: Una fachada para un sistema de compilacin
class Scannerpublic:
Scanner(istream&);virtual ~Scanner();v r ua o en can ;
private:istream& _inputStream;
class Parser {public:
virtual ~Parser();virtual void Parse(Scanner&, ProgramNodeBuilder&);
};
66
F
7/27/2019 8 Patrones
67/137
class ProgramNodeBuilder {
Ejemplo: Una fachada para un sistema de compilacin
public:ProgramNodeBuilder();virtual ProgramNode* NewVariable ( const char* variableName ) const;
* * ,ProgramNode* expression) const;
virtual ProgramNode* NewReturnStatement ( ProgramNode* value ) const;virtual ProgramNode* NewCondition ( ProgramNode* condition,
ProgramNode* truePart,
ProgramNode* falsePart ) const;// ...*
private:ProgramNode* _node;
};
67
Facadeemp o: na ac a a para un s s ema e comp ac n
7/27/2019 8 Patrones
68/137
class ProgramNode {public:
emp o: na ac a a para un s s ema e comp ac n
virtual void GetSourcePosition(int& line, int& index);// ...
// child manipulationvirtual void Add(ProgramNode*);virtual void Remove(ProgramNode*);// ...
protected:
ProgramNode();};
class CodeGenerator {public:
virtual void Visit(StatementNode*);
v r ua vo s xpress on o e ;// ...
protected:CodeGenerator B tecodeStream&
68protected:
BytecodeStream& _output;};
F
7/27/2019 8 Patrones
69/137
void ExpressionNode::Traverse (CodeGenerator& cg) {Ejemplo: Una fachada para un sistema de compilacin
cg. s s ;ListIterator i(_children);for (i.First(); !i.IsDone(); i.Next()) {
i.CurrentItem ->Traverse c}}
class Compiler { // Clase Facadepu c:
Compiler();virtual void Compile(istream&, BytecodeStream&);
void Compiler::Compile ( istream& input, BytecodeStream& output ) {Scanner scanner(input);
rogram o e u er u er;Parser parser;parser.Parse(scanner, builder);RISCCodeGenerator enerator out ut
69
ProgramNode* parseTree = builder.GetRootNode();
parseTree->Traverse(generator);}
7/27/2019 8 Patrones
70/137
.
{Proporcionar un representante o substituto de otro objetopara controlar el acceso a este.
z Tambin conocido como.
{Surrogate (substituto).
o vac n.
{Retrasar el coste de creacin e inicializacin de un objetohasta ue sea realmente necesario.
{Ej.: al abrir un documento, no abrir las imgenes que no seanvisibles.
aTextDocument:
image
anImageProxy:
fileName
anImage:
data
70
en memoria en disco
7/27/2019 8 Patrones
71/137
zMotivacin.
71
7/27/2019 8 Patrones
72/137
.{Cuando hay necesidad de una referencia a un objeto ms
flexible o sofisticada que un puntero.{Proxy Remoto: un representante para un objeto que se
encuentra en otro espacio de direcciones.{Proxy Virtual: Crea objetos costosos por encargo (ej.:
mage roxy .
{Proxy de Proteccin: Controla el acceso al objeto original(permisos de acceso).{Referencia inteligente: sustituto de un puntero, que lleva a
cabo operaciones adicionales cuando se accede a un objeto(ver ejemplo operadores C++):z on ar e n mero e re erenc as.zCargar un objeto persistente en memoria.z Bloquear el objeto cuando se accede a l (no modificacin
72
.z
7/27/2019 8 Patrones
73/137
z
73
7/27/2019 8 Patrones
74/137
z Participantes.{ Proxy.
z Mantiene una referencia que permite al proxy acceder al objeto real.z Proporciona una interfaz igual que la del sujeto real.z Controla el acceso al sujeto real, y puede ser responsable de crearlo y
borrarlo.z Otras responsabilidades, dependen del tipo de proxy:
, . Proxy virtual: Puede guardar informacin adicional sobre el sujeto, para
retardar el acceso al mismo. Proxy de proteccin: comprueba que el llamador tiene permiso para
.
{ Subject.z Define una interfaz comn para el RealSubject y el Proxy, de tal
.{ RealSubject.z Define el objeto real que el proxy representa.
74
.{ El proxy redirige peticiones al sujeto real cuando sea necesario,
dependiendo del tipo de proxy.
7/27/2019 8 Patrones
75/137
.{ Introduce un nivel de indireccin adicional, que tiene muchos
posibles usos:z n proxy remo o pue e ocu ar e ec o e que un o e o res e en
otro espacio de direcciones.z Un proxy virtual puede realizar optimizaciones, como crear objetos
.z Tanto los proxies de proteccin, como las referencias inteligentes
permiten realizar tareas de mantenimiento adicionales cuando se.
{ Otra optimizacin: copy-on-write.z Copiar un objeto grande puede ser costoso.
,gasto.z El sujeto mantiene una cuenta de referencias, slo cuando se hace
75
, .String del ejemplo de operadores C++).
class Image;extern Image* LoadAnImageFile(const char*);// external function
7/27/2019 8 Patrones
76/137
class ImagePtr {public:
*.{ Se pueden explotar las
siguientes caractersticas de
virtual ~ImagePtr();virtual Image* operator->();
virtual Image& operator*();os engua es:z Sobrecargar el operador de
acceso a miembros -> en
private:Image* LoadImage();
private:*. _
const char* _imageFile;
};ImagePtr::ImagePtr (const char* theImageFile) {
_imageFile = theImageFile;_image = 0;
}
*if (_image == 0) {_image = LoadAnImageFile(_imageFile);
}
76
return _image;}
7/27/2019 8 Patrones
77/137
Ima e* Ima ePtr::o erator->return LoadImage();
}Image& ImagePtr::operator* () {
re urn oa mage ;}
ImagePtr image = ImagePtr("anImageFileName");image->Draw(Point(50, 100));
// (image.operator->())->Draw(Point(50, 100))
z Sobrecargar -> no funciona si necesitamos saber a qu operacin sellama: entonces hay que definir dichar operacin en el proxy y redirigir la
.z A veces no hace falta que el proxy conozca el tipo concreto del sujetoreal (si es suficiente con la interfaz de la clase abstracta Subject).
77
Pr x
7/27/2019 8 Patrones
78/137
Ejemplo: Un Proxy Virtualclass Graphic {
virtual ~Graphic();virtual void Draw(const Point& at) = 0;virtual void HandleMouse(Event& event) = 0;virtual const Point& GetExtent() = 0;virtual void Load(istream& from) = 0;virtual void Save(ostream& to) = 0;
protected:Graphic();
};class Image : public Graphic {public:
Image(const char* file); // loads image from a filevirtual ~Image();virtual void Draw const Point& atvirtual void HandleMouse(Event& event);virtual const Point& GetExtent();virtual void Load(istream& from);
78
private:
// ...};
Pr x
7/27/2019 8 Patrones
79/137
Ejemplo: Un Proxy Virtualclass Ima eProx : ublic Gra hic // la clase roxpublic:
ImageProxy(const char* imageFile);virtual ~ImageProxy();
v r ua vo raw cons o n a ;virtual void HandleMouse(Event& event);virtual const Point& GetExtent();virtual void Load istream& fromvirtual void Save(ostream& to);
protected:Image* GetImage();pr va e:
Image* _image;Point _extent;char* fileName_
};
79
Pr x
7/27/2019 8 Patrones
80/137
Ejemplo: Un Proxy VirtualIma eProx ::Ima eProx const char* fileName const Point& ImageProxy::GetExtent () {
_fileName = strdup(fileName);_extent = Point::Zero; // don't know extent yet_image = 0;
_ex en == o n :: ero_extent = GetImage()->GetExtent();
}
return _extent;Image* ImageProxy::GetImage() {
if (_image == 0) {_image = new Image(_fileName);
}void ImageProxy::Draw (const Point& at) {
GetImage()->Draw(at);
return _image;
}
void ImageProxy::HandleMouse (Event& event) {
GetImage()->HandleMouse(event);}
void ImageProxy::Save (ostream& to) {to _extent >> _fileName;
80
Pr x
7/27/2019 8 Patrones
81/137
Ejemplo: Un Proxy Virtual
class TextDocument {public:
TextDocument();
*// ...
};
TextDocument* text = new TextDocument;
// ...text->Insert(new ImageProxy("anImageFileName"));
81
Ejercicio (Junio de 208)ea a ap cac n e pe os v s a en emas an er ores:
7/27/2019 8 Patrones
82/137
7/27/2019 8 Patrones
83/137
z En el contexto de la aplicacin anterior, supnque slo se puede acceder al disponible de unacuenta de pago si se ha introducido una clave.Utilizando patrones de diseo, implementa enC++ un Proxy de Proteccin que asegure que se
accede al disponible de la cuenta slo si la clavees correcta (supn que la clave se pide por laconsola). La clave se almacena en el proxy, y
ste recuerda si ya se ha introducidocorrectamente o no.
Solucin (1)#i ncl ude "st daf x. h"#i ncl ude #i ncl ude
usi ng st d: : st r i ng;
7/27/2019 8 Patrones
84/137
usi ng st d: : ci n;cl ass Cuent a
publ i c:vi r t ual i nt obt ener Di sponi bl e ( ) = 0;
};
{pr i vat e:
i nt di sponi bl e;
Cuent aReal ( i nt d ) : di sponi bl e ( d) {}
i nt obt ener Di sponi bl e( ) {return di sponi bl e; }};
{pr i vat e:
Cuent aReal * cuent a;
bool cor r ect a;bool i nt r o;
publ i c:,
cl ave( psswd) , cuent a( &c) , i nt r o( f al se) , cor r ect a( f al se) {}i nt obt ener Di sponi bl e( ) ;
};
Solucin (2)i nt Pr oxyCuent a: : obt ener Di sponi bl e( ) {
i f (correcta) return cuent a- >obt ener Di sponi bl e( ) ;el se i f ( ! i nt r o) {
7/27/2019 8 Patrones
85/137
i nt ro = true;st r i ng cl ;cout > cl ;i f ( cl == cl ave) {
cor r ect a = true;return cuent a- >obt ener Di sponi bl e( ) ;
}el se {
cor r ect a = f al se;cout
7/27/2019 8 Patrones
86/137
z Propsito.{ Convierte el interfaz de una clase en otro ue es era el cliente.{ El adapter permite trabajar juntas a clases que de otra forma no podran por
tener interfaces incompatibles.
zTambin conocido como.{ Wrapper (envoltorio).
z Motivacin.
,no puede hacerlo porque su interfaz no coincide con la interfaz especfica
de dominio que requiere la aplicacin.. . ,
Shape.z Queremos reutilizar una clase existente TextView para implementar TextShape
(quiz no tengamos el cdigo fuente de TextView).
z Solucin: Definir una clase TextShape que adapte el interfaz de TextView aShape.
z Se puede hacer de dos maneras:
86
TextView.
Adaptador de objeto: Componiendo un objeto TextView dentro de un TextShape, e
implementando TextShape en trminos de la interfaz de TextView.
7/27/2019 8 Patrones
87/137
zMotivacin.
{Ada tador de ob eto.
87
7/27/2019 8 Patrones
88/137
zEstructura.
{
Ada tador de clase.
88
7/27/2019 8 Patrones
89/137
zEstructura.
{
Ada tador de ob eto.
89
7/27/2019 8 Patrones
90/137
z Introduccin.z Patrones de Creacin.z Patrones Estructurales.
.{Iterator.
{Observer.
{Template Method.
{State.
{Strate .
{Command.
909090
.z Conclusiones.z Bibliografa.
7/27/2019 8 Patrones
91/137
zTratan sobre algoritmos y la asignacin de
res onsabilidades entre ob etos.zDescriben no slo patrones de clases y,
entre ellos.zCaracterizan un flujo de control complejo,
zPermiten que el diseador se concentres o en c mo n erconec ar o e os.
7/27/2019 8 Patrones
92/137
.{ Proporciona un medio de acceder a los elementos de un
contenedor secuencialmente sin exponer su representacin
.z Tambin Conocido Como.
{ Cursor.
z Motivacin.
{ Un contenedor (p.ej.: una lista) debe proporcionar un medio denave ar sus datos secuencialmente sin ex oner surepresentacin interna.
{ Se debe poder atravesar la lista de varias maneras,dependiendo de lo que se quiera hacer.
{ Probablemente no interesa aadir a la lista operaciones pararealizar los diferentes recorridos.{ Puede necesitarse hacer ms de un recorrido simultneamente.
92
{ Dar la responsabilidad de acceder y recorrer el objeto lista a unobjeto Iterator.
7/27/2019 8 Patrones
93/137
z Motivacin.
List ListIterator list
+ Count()+ Append(Element)+ Remove(Element) + First()
+
- index
+ IsDone()
+ CurrentItem()
{ Antes de instanciar el ListIterator, se ha de proporcionar la lista.
{ Una vez que se tiene la instancia, se puede acceder a los.
{ Separar el mecanismo de recorrido del objeto lista, nos permitedefinir iteradores que implementen distintas estrategias.
93
7/27/2019 8 Patrones
94/137
z Motivacin.{ El iterador y la lista estn acoplados: el cliente sabe que lo que se est recorriendo es una lista.
{ Es mejor poder cambiar el contenedor sin tener que cambiar el cdigo cliente: iteracinpolimrfica.
AbstractList
+CreateIterator()
+ Count()
Iterator
+ First()
++ ppen emen
+ Remove(Element)
+ IsDone()
+ CurrentItem()
Client
1 *list
ListSkipList ListIterator SkipListIterator 1
skiplist*
{ Podemos hacer responsables a las listas de crear sus propios iteradores, mediante un factory
94
method (CreateIterator).
{ Se puede definir algoritmos generales que usan un iterador genrico (en C++: for_each, find_if,
count, etc)
z Aplicabilidad Usar el patrn :
7/27/2019 8 Patrones
95/137
z Aplicabilidad. Usar el patrn :
representacin interna.
{ para permitir varios recorridos sobre contenedores.
{ para proporcionar una interfaz uniforme para recorres distintos tiposde contenedores (esto es, permitir la iteracin polimrfica).
z Estructura.
Aggregate
+CreateIterator ()
+First ()
+Next ()
+IsDoneClient
+CurrentItem ()
ConcreteAggregate
+CreateIterator () ConcreteIterator
95return new ConcreteIterator (this)
7/27/2019 8 Patrones
96/137
.{ Iterator.
z Define una interfaz para recorrer los elementos y acceder a ellos.
{ ConcreteIterator.z Implementa la interfaz Iterator.z Mantiene la posicin actual en el recorrido del agregado.
{Aggregate.z Define una interfaz para crear un objeto Iterator.
{ ConcreteAggregate.z Implementa una interfaz de creacin del Iterator para devolver una
instancia del ConcreteIterator apropiado.
z Colaboraciones.{ Un ConcreteIteratorsabe cul es el objeto actual del agregado ypuede calcular el objeto siguiente del recorrido.
96
7/27/2019 8 Patrones
97/137
.{ Permite variaciones en el recorrido de un agregado.{ Los iteradores simplifican la interfaz del contenedor.{ Se puede hacer ms de un recorrido a la vez sobre un
agregado.
.{Quin controla la iteracin?.
z El cliente controla la iteracin: iterador externo..
{Quin define el algoritmo de recorrido?z El iterador.
agrega o, y e era or s o a macena e es a o e aiteracin. A este tipo de iterador se le llama cursor.{Cmo de robusto es el iterador?
97
recorrido (y se hace sin copiar el agregado).
7/27/2019 8 Patrones
98/137
mp emen ac n.
{Operaciones adicionales del iterador.z
Previous. Otras como SkipTo.
{Usar iteradores polimrficos en C++.
mtodo de fabricacin.
z El cliente adems es responsable de borrarlos (propenso a.
{ Iteradores para Composites.z Los iteradores externos pueden ser complicados de implementar
en es ruc uras recurs vas.{NullIterators.
z Es un iterador de enerado ue a uda a mane ar condiciones
98
lmite.
I r r
Ejemplo
7/27/2019 8 Patrones
99/137
. .
template class List {
List(long size = DEFAULT_LIST_CAPACITY);long Count() const;Item& Get(long index) const;// ...
};
< >class Iterator {public:
virtual void First() = 0;
virtual void Next() = 0;virtual bool IsDone() const = 0;virtual Item CurrentItem() const = 0;
99Iterator();
};
I r r
Ejemplo
7/27/2019 8 Patrones
100/137
. .
template class ListIterator : public Iterator {
ListIterator(const List* aList) _list(aList), _current(0) {}virtual void First() {_current = 0;}virtual void Next() {_current++;}virtual bool IsDone() const {return _current >= _list->Count(); }virtual Item CurrentItem() const;
private:* _
long _current;};
Item ListIterator::CurrentItem () const {if (IsDone()) throw IteratorOutOfBounds;return _list->Get(_current);
100
}// Se puede implementar un ReverseListIterator, con First
// posicionando el iterador al final de la lista, y Next decrementando
I r r
Ejemplo
7/27/2019 8 Patrones
101/137
. so e tera or.
void PrintEmployees (Iterator& i) {for i.First ; !i.IsDone ; i.Next
i.CurrentItem()->Print();}
}
List* employees;
// ...ListIterator forward(employees);ReverseListIterator backward(employees);PrintEmployees(forward);PrintEmployees(backward);
101
I r r
Ejemplo
4 Evitar ajustarse a una implementacin concreta de la lista
7/27/2019 8 Patrones
102/137
4. Evitar ajustarse a una implementacin concreta de la lista.
{ Supongamos que tenemos SkipList y SkipListIterator.{ Se puede introducir unAbstractList para estandarizar la interfaz de la lista
(List y SkipList son subclases de AbstractList).{ Para permitir iteracin polimrfica,AbstractList define un factory method
CreateIterator.
class AbstractList {
public:virtual Iterator* CreateIterator() const = 0;
template
Iterator* List::CreateIterator () const {return new ListIterator(this);...
};
// we know onl that we have an AbstractList
AbstractList* employees;// ...Iterator* iterator = employees->CreateIterator();
102
r n mp oyees era or ;delete iterator;
I r r
Ejemplo
5 Ase urarse de ue los iteradores se borran
7/27/2019 8 Patrones
103/137
5. Ase urarse de ue los iteradores se borran.
{ Crear un IteratorPtr, que actua de Proxy para un Iterator.
{ Se ocupa de borrar el Iterator cuando se sale de mbito.
template class IteratorPtr {public:
* _~IteratorPtr() { delete _i; }
Iterator* operator->() { return _i; }Iterator& operator*() { return *_i; } AbstractList* employees;// ...
private:// disallow copy and assignment to avoid// multiple deletions of _i:
terator tr< mp oyee >iterator(employees->CreateIterator());
PrintEmployees(*iterator);
IteratorPtr& operator=(const IteratorPtr&);
private:Iterator* _i;
103
};
I r r
6 Un iterador interno
Ejemplo
7/27/2019 8 Patrones
104/137
6. Un iterador interno.
{ El iterador controla la iteracin, y aplica una operacin a cada elemento.
{ La operacin se puede configurar:
, .z Mediante subclasificacin.
template class ListTraverser {
public:ListTraverser(List* aList):_iterator(aList) { };
template bool ListTraverser::Traverse () {bool result = false;
bool Traverse();protected:virtual bool ProcessItem(const Item&) = 0;
private:
_ . _ . _ .result = ProcessItem(_iterator.CurrentItem());if (result == false) break;
}
ListIterator _iterator;};
}
104
I r r
Ejemplo
7/27/2019 8 Patrones
105/137
. n tera or nterno
{ Imprimir los n primeros empleados de una lista.
*public:PrintNEmployees(List* aList, int n) :
ListTraverser(aList),_total(n), _count(0) { }
protected:bool ProcessItem(Employee* const&);
int _total;int _count;
};
bool PrintNEmployees::ProcessItem (Employee* const& e) {_count++;
105
-return _count < _total;
}
I r r
Ejemplo
7/27/2019 8 Patrones
106/137
< *>*
. n era or n erno
{ Imprimir los n primeros empleados de una lista.
// ...PrintNEmployees pa(employees, 10);pa.Traverse();
{ Comparacin con un iterador externo:
ListIterator i(employees);=
for (i.First(); !i.IsDone(); i.Next()) {count++;i.CurrentItem()->Print();
if (count >= 10) break;}
106
I r r
Ejemplo
7/27/2019 8 Patrones
107/137
. n tera or nterno
{ Pueden encapsular distintos tipos de operaciones.
class FilteringListTraverser {public:FilteringListTraverser(List* aList);
template void FilteringListTraverser::Traverse () {bool result = false;for (_iterator.First();!_iterator.IsDone();_iterator.Next()) {
bool Traverse();protected:
virtual bool ProcessItem(const Item&) = 0;virtual bool TestItem(const Item&) = 0;
if (TestItem(_iterator.CurrentItem())) {result = ProcessItem(_iterator.CurrentItem());
if (result == false) break;
private:ListIterator _iterator;
};
}return result;
}
107
7/27/2019 8 Patrones
108/137
rop s o.{Define una dependencia de uno-a-muchos entre objetos, de
forma ue cuando un ob eto cambie de estado se notifi ueactualicen automticamente todos los objetos que dependende l.
.{Dependents, Publish-Subscribe
z Motivacin.{Mantener consistencia entre objetos relacionados.{No queremos obtener dicha consistencia aumentando el
.{Ej.: separacin de la presentacin en GUI de los datos deaplicacin subyacente.
108
7/27/2019 8 Patrones
109/137
z Motivacin.
A
C
D
10
20
30A B C DX 60 20 15 5
Y 40 25 15 20B
0
A B C DZ 10 10 20 60
Modelo
A: 40%B: 25%
109
:
D: 20%
z Aplicabilidad.
7/27/2019 8 Patrones
110/137
{ Cuando una abstraccin tiene dos aspectos y uno depende del otro.
{ Cuando un cambio en un objeto requiere cambiar otros, y no sabemoscuntos ha ue cambiar.
{ Cuando un objeto debera ser capaz de notificar a otros sin hacersuposiciones sobre quines son dichos objetos (esto es, no queremos
.
z Estructura.
Subject Observer observers
+Attach (Observer)+Detach (Observer)+Notify ()
+Update()
forall o in observers
....
.
ConcreteSubject
ConcreteObserver
- observerState0..1
110+GetState ()
+SetState ()
- subjectState +Update ()
return subjectState observerState=
subject->GetState()
z Participantes.u ec
7/27/2019 8 Patrones
111/137
u ec .z Conoce a sus observadores, que pueden ser un nmero arbitrario.z Proporciona un interfaz para aadir y quitar objetos Observer.
server.z Define un interfaz de actualizacin para los objetos que deben ser
notificados sobre cambios en un sujeto..
z Almacena estado de inters para ConcreteObservers.
z Manda notificaciones a sus observadores cuando su estado cambia..
z Mantiene una referencia a objetos ConcreteSubject.z Almacena el estado que debe ser consistente con el del sujeto.
estado consistente con el del sujeto.
111
z Colaboraciones.
7/27/2019 8 Patrones
112/137
{ El ConcreteSubject notifica a sus observadores cada vez que seproduce un cambio que pudiera hacer que el estado de estos fueseinconsistente con el su o.
{ Despus de ser notificado del cambio, un ConcreteObserverpuedepedir al subject ms informacin.
:ConcreteSubjectbarDiagram
:ConcreteObserversectorDiagram
:ConcreteObserver
SetState()Notify()
Update()
Update()
GetState()
112
7/27/2019 8 Patrones
113/137
.{ Permite modificar los sujetos y observadores de manera
independiente.
e pue en reu zar os su e os s n sus o serva ores yviceversa.{ Se pueden aadir observadores sin modificar el sujeto u otros
.{ Acoplamiento abstracto entre sujeto y observador. El sujeto no
conoce la clase concreta de ningn observador (el acoplamiento.{ Capacidad de comunicacin mediante difusin. La notificacin
del sujeto se enva automticamente a todos los observadoressuscritos. Se ueden aadir uitar observadores en cual uier
momento.{ Actualizaciones inesperadas. Una operacin aparentementeinofensiva sobre el sujeto puede desencadenar una cascada de
113
cam os en os o serva ores.
7/27/2019 8 Patrones
114/137
.{ Correspondencia entre sujetos y observadores.
z Que el sujeto guarde referencias a los observadores a los que debe
no car.{ Observar ms de un sujeto.z Ej.: una hoja de clculo puede observar ms de un origen de datos.
x en er a n er az e ac ua zac n para que e o serva or sepaqu sujeto se ha actualizado (quiz simplemente el sujeto se pase
a s mismo como parmetro del update()).{ Quin dis ara la actualizacin?z Las operaciones que cambien el estado del sujeto llaman a Notify().
Ventaja: los clientes no tienen que hacer nada. Inconveniente: no es ptimo si hay varios cambios de estado seguidos.
zLos clientes llaman a Notify(): Ventaja: se puede optimizar llamando a notify slo despus de varios
cambios. Inconveniente: los clientes tienen la res onsabilidad aadida de llamar
114
a Notify().
z Implementacin
7/27/2019 8 Patrones
115/137
z Implementacin.{Referencias perdidas a sujetos borrados.
z Una manera de evitarlo es notificar a los observadorescuando se borra un sujeto.
consigo mismo antes de la notificacin:z Ha ue tener cuidado con las o eraciones heredadas.
void MySubject::Operation (int newValue) {
// trigger notification_myInstVar += newValue;// update subclass state (too late!)
115
7/27/2019 8 Patrones
116/137
.{Evitar protocolos especficos del obervador: los modelos
push y pull.
z Las implementaciones de observer suelen hacer que el sujetoenvie informacin adicional como parmetro de Update().zDos extremos:
,los observadores o no.
Inconveniente: observadores menos reutilizables. Modelo Pull: el sujeto no enva nada, y los observadores piden
espu s os e a es exp c amen e.Inconveniente: puede ser poco eficiente.
{Especificar las modificaciones de inters explcitamente:
solo aquellos eventos que les interesen.z Los observadores se subscriben a aspectos del sujeto.
116
z Implementacin..
7/27/2019 8 Patrones
117/137
z Si la relacin de dependencia entre sujetos y observadores es compleja, puede sernecesario un objeto intermedio para la gestin de cambios (ChangeManager).
z Minimizar el traba o necesario ara ue los observadores refle en los cambios en el
sujeto.z Ej.: si varios sujetos han de cambiarse, asegurarse de que se notifique a los
observadores slo despus del cambio en el ltimo sujeto.
Subject
+
Observer
+
subjects
1..*0..*
ChangeManagerchman
1 Subject-Observer mapping
observers
+Detach (Observer)+Notify ()
+Register (Subject,Observer)
+Unregister (Subject,Observer)
+Notify ()
->
Marcar todos los observersa actualizar.
chman->Registar(this,o)
SimpleChangeManager DAGChangeManager
marcados.
117
+Register (Subject,Observer)+Unregister (Subject,Observer)+Notify ()
+Register (Subject,Observer)+Unregister (Subject,Observer)+Notify ()
forall s in subjects:forall o in observers:
o->Update(s)
rv r
Ejemplo class Subject {
public:virtual ~Subject();
virtual void Attach(Observer*);
7/27/2019 8 Patrones
118/137
class Observer {public:
virtual ~ Observer();
virtual void Attach(Observer );virtual void Detach(Observer*);virtual void Notify();
virtual void Update (Subject*theChangedSubject) = 0;
// soporte de mltiples subjects
Subject();private:
List *_observers;
Observer();
};
};void Subject::Attach (Observer* o) {
_observers->Append(o);
void Subject::Detach (Observer* o) {_observers->Remove(o);
}
void Subject::Notify () {ListIterator i(_observers);for (i.First(); !i.IsDone(); i.Next()) {
118
. -}
}
rv r
Ejemplo
class Di italClock: ublic Wid et ublic
Observer {
7/27/2019 8 Patrones
119/137
// Concrete subjectpublic:
ClockTimer();
Observer {public:
DigitalClock(ClockTimer*);
virtual int GetHour();virtual int GetMinute();virtual int GetSecond();
v r ua ~ g a oc ;virtual void Update(Subject*);// overrides Observer operationvirtual void Draw
};
void ClockTimer::Tick () {
// overrides Widget operation;// defines how to draw the digital clock
private:// update internal time-keeping state// ...Notify();
oc mer _su ec ;};
DigitalClock::DigitalClock (ClockTimer* s) {_su ect = s;_subject->Attach(this);
}~
119
_subject->Detach(this);
}
rv r
Ejemplo
void DigitalClock::Update (Subject* theChangedSubject) {
7/27/2019 8 Patrones
120/137
g p ( j g j ) {if (theChangedSubject == _subject) Draw();
}int hour = _subject->GetHour(); // get the new values from the subject
int minute = _subject->GetMinute();// etc.// draw the digital clock
},
public:AnalogClock(ClockTimer*);virtual void Update(Subject*);
virtual void Draw();// ...};
120
ClockTimer* timer = new ClockTimer;AnalogClock* analogClock = new AnalogClock(timer);
DigitalClock* digitalClock = new DigitalClock(timer);
rv r
Usos Conocidos
=
7/27/2019 8 Patrones
121/137
{AWT/Swing{ Javabeans
z MVC en el sistema de ventanas de Smalltalk{Model=Subject
{Controller=Cualquier objeto que cambie el estado de Subject
z MVC en entornos web (J2EE){Model=EJB{View=JSP
=
121
z Pro sito.{ Definir el esqueleto de un algoritmo delegando en las subclases
7/27/2019 8 Patrones
122/137
{ Definir el esqueleto de un algoritmo, delegando en las subclasesalguno de sus pasos.
su estructura.
z Motivacin.{ Ej.: MFCs, abrir un fichero.
Document A licationdocs
void Application::OpenDocument (const char* name) {
if (!CanOpenDocument(name)) {
+Abrir()+Cerrar()+Guardar()
+AddDocument()+OpenDocument()+DoCreateDocument()
.. return;
}Document* doc = DoCreateDocument();
+ o e a
+AboutToOpenDocument()
M Document MyApplication
_docs->AddDocument(doc);AboutToOpenDocument(doc);doc->Open();
122+DoCreateDocument()+CanOpenDocument()
+AboutToOpenDocument()
+DoRead()
return MyDocument
-}
}
z Aplicabilidad.
{Para implementar las partes de un algoritmo que no cambian
7/27/2019 8 Patrones
123/137
{Para implementar las partes de un algoritmo que no cambian,y dejar que las subclases implementen el comportamiento
.
{Cuando el comportamiento repetido de varias subclasesdebera factorizarse y localizarse en una clase comn, paraevitar cdigo duplicado.
{Para controlar las extensiones de las subclases.s ruc ura. ClaseAbstracta
+TemplateMethod()+PrimitiveOperation1() +PrimitiveOperation2()
+ PrimitiveOperation1()PrimitiveOperation2()
123
ConcreteClass
+PrimitiveOperation1()+PrimitiveOperation2()
z Propsito.{ Permitir ue un ob eto modifi ue su com ortamiento cada vez ue cambie su
estado interno.
7/27/2019 8 Patrones
124/137
{ Parecer que cambia la clase del objeto.z Tambin conocido como.
{ Objets for state (estados como objetos).z Motivacin.
{ TCPConnection ara re resentar una conexin de red.{ Puede estar en distintos estados: establecida, escuchando y cerrada.{ El efecto de cada peticin sobre cada objeto depende del estado en el que est.
124
zEstructura.
7/27/2019 8 Patrones
125/137
zEstructura.
125
z Propsito.
{ Define una familia de algoritmos, encapsula cada uno de ellos, y los hace
7/27/2019 8 Patrones
126/137
intercambiables.
{ Permite que un algoritmo vare independientemente de los clientes que los usan.
z Tambin conocido como.{ Policy (poltica).
.
{ Ej.: Algoritmos para dividir en lneas un flujo de texto.
{ Clases que encapsulen los distintos algoritmos de divisin. Un algoritmo as.
126
zEstructura.
7/27/2019 8 Patrones
127/137
st uctu a
127
z Propsito..
{ Permite parametrizar a los clientes con diferentes peticiones hacer
7/27/2019 8 Patrones
128/137
{ Permite parametrizar a los clientes con diferentes peticiones, hacercola o llevar un registro de peticiones, as como deshacer las
.z Tambin conocido como.
{ Action, Transaction.z Motivacin.
{ Framework grfico tipo MFC. Peticiones de los distintos widgets
encapsuladas como objetos.
128
o vac n.
7/27/2019 8 Patrones
129/137
129
s ruc ura.
7/27/2019 8 Patrones
130/137
130
z Propsito.
{ Evita acoplar el emisor de una peticin a su receptor, dando a msd bj t l ibilid d d d l ti i
7/27/2019 8 Patrones
131/137
de un objeto la posibilidad de responder a la peticin.
cadena hasta que es procesada por algn objeto.
z Motivacin.
{ Ej.: ayuda sensible al contexto en una GUI.
{ Si no existe ayuda para una parte de la interfaz, se muestra ayudaara una arte ms eneral.
131
zMotivacin.
7/27/2019 8 Patrones
132/137
132
zEstructura.
7/27/2019 8 Patrones
133/137
133
n ro ucc n.z Patrones de Creacin
7/27/2019 8 Patrones
134/137
z Patrones de Creacin.
.z Patrones de Comportamiento.
.z
Bibliografa.
134134134
tienen los expertos a la hora de disear.
7/27/2019 8 Patrones
135/137
p
zLos patrones ayudan a generar software maleable(software que soporta y facilita el cambio, la reutilizacin.
zLos patrones de diseo son guas, no reglas rigurosas.
zCada patrn describe la solucin a problemas que se,
se puede usar esa solucin todas las veces que hagafalta.
135
n ro ucc n.z Patrones de Creacin
7/27/2019 8 Patrones
136/137
z Patrones de Creacin.
.z Patrones de Comportamiento..
zBibliografa.
136136136
z es gn pa erns, e emen s o reusa e o ec -oriented software Gamma Helm Jonhnson
7/27/2019 8 Patrones
137/137
oriented software . Gamma, Helm, Jonhnson,
. ,espaol en 2003).
z
Applying UML and Patterns. An introduction to-Iterative Development. 3rd Edition. Craig
. . .
137137137
.