Documentos de Académico
Documentos de Profesional
Documentos de Cultura
8 Patrones PDF
8 Patrones PDF
Tema 7
Grupo 46
TACC II
Curso 2008/09
1
Indice
z Introduccin.
I t d
i
{ Patrones.
{ Descripcin de los Patrones.
{ Ejemplo: Patrones en el MVC de Smalltalk.
{ El catlogo de patrones.
z
z
z
z
z
Patrones de Creacin.
Patrones Estructurales.
Patrones de Comportamiento.
C
Conclusiones.
l i
Bibliografa.
2
Introduccin
z Di
Diseo
especfico
fi para ell problema,
bl
pero generall como
para 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 entre
objetos en muchas soluciones de diseo.
3
Patrn
z Un esquema que se usa para solucionar un problema
problema.
z El esquema ha sido probado extensivamente, y ha
funcionado. Se tiene experiencia sobre su uso.
z Existen
E i t en muchos
h d
dominios:
i i
{
{
{
{
Patrones de Diseo
z R
Reutilizar
tili
di
diseos
abstractos
b t t que no iincluyan
l
d
detalles
t ll
de la implementacin.
z Un patrn es una descripcin del problema y la esencia
de su solucin, q
que se p
puede reutilizar en casos
distintos.
z Es
E una solucin
l i adecuada
d
d a un problema
bl
comn.
z A
Asociado
i d a orientacin
i t i a objetos,
bj t
pero ell principio
i i i
general es aplicable a todos los enfoques de diseo
software.
5
Patrones de Diseo
z Documentar
D
t lla experiencia
i
i en ell di
diseo,
en
forma de un catlogo de patrones.
z Categoras de patrones:
{ De creacin: implica el proceso de instanciar objetos.
{ Estructurales: composicin de objetos.
{ De comportamiento
comportamiento: cmo se com
comunican
nican los objetos
objetos,
cooperan y distribuyen las responsabilidades para
lograr sus objetivos.
6
Patrones de Diseo
Estructura de un patrn
z Nombre
N b del
d l patrn.
t
{ Describe el problema de diseo, junto con sus soluciones y
consecuencias.
{ Vocabulario
V
b l i d
de di
diseo.
z Problema.
{ Describe cundo aplicar el patrn.
{ Explica el problema y su contexto.
z Solucin.
{ Elementos que forman el diseo, relaciones, responsabilidades.
{ No un diseo concreto, sino una plantilla que puede aplicarse en
muchas situaciones distintas.
z Consecuencias.
Consecuencias
{ Resultados, ventajas e inconvenientes de aplicar el patrn.
{ P.ej.: relacin entre eficiencia en espacio y tiempo; cuestiones de
implementacin etc
implementacin,
etc.
7
Patrones de Diseo
Ejemplo: MVC de Smalltalk
zModelo/Vista/Controlador.
40
60
20
15
40
25
15
20
10
10
10
20
60
D
A
30
20
Modelo
A:
B:
C
C:
D:
40%
25%
15%
20%
Patrones de Diseo
Ejemplo: MVC de Smalltalk
zS
Separar llos objetos
bj t con llos d
datos
t ((modelo),
d l ) sus
visualizaciones (vistas) y el modo en que la interfaz
reacciona ante la entrada al usuario (controlador).
(
)
z Separar
p
estos componentes,
p
p
para aumentar la
flexibilidad y reutilizacin.
zD
Desacoplar
l vistas
i
d
de modelos,
d l
mediante
di
un protocolo
l d
de
subscripcin/notificacin.
z Cada vez que cambian los datos del modelo, avisar a
que dependen
p
de l. Estas se actualizan.
las vistas q
9
Patrones de Diseo
Ejemplo: MVC de Smalltalk
z Patrn Observer,
Observer ms general (dependencias entre
objetos).
z Las vistas se pueden anidar: Vistas compuestas y
simples.
{ Generalizacin: Patrn Composite.
Composite
El catlogo de patrones
Propsito
Creacin
Estructurales
De Comportamiento
m
mbito
Clase
Factory Method
Interpreter.
Template Method.
Method
Objeto
j
Abstract Factory
Builder
Prototype
Singleton
Chain of Responsibility.
Command.
Iterator.
Mediator.
Memento.
Observer.
State.
Strategy.
11
Visitor.
El catlogo
de patrones
Relaciones entre
los patrones.
12
Indice
z Introduccin.
Introduccin
z Patrones de Creacin.
z
z
z
z
{Singleton
{Singleton.
{Abstract Factory.
{Factory Method.
Patrones Estructurales.
Patrones de Comportamiento.
Concl siones
Conclusiones.
Bibliografa.
13
Patrones de Creacin
z Ab
Abstraen
t
ell proceso de
d instanciacin
i t
i i
z Ayudan a que el sistema sea independiente de
cmo se crean
crean, componen y representan los
objetos.
z Flexibilizan:
{
{
{
{
qu se crea
quin lo crea
cmo se crea
cundo se crea
Singleton
z Intencin.
I t
i
{ 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
sola instancia
instancia, por ejemplo:
z
z
z
z
Un gestor de ventanas
Una nica cola de impresin
Un nico sistema de ficheros
Un nico fichero de log, o un nico repositorio.
Singleton
z Aplicabilidad.
{ Cuando debe haber una sola instancia, y debe ser accesible a los
clientes desde un punto de acceso conocido.
{ Cuando la nica instancia debe ser extensible mediante
subclasificacin, y los clientes deben ser capaces de usar una
instancia extendida sin modificar su cdigo.
cdigo
z Estructura.
Singleton
static Singleton uniqueInstance
singletonData
static Singleton Instance ()
SingletonOperation ()
GetSingletonData ()
return uniqueInstance
16
Singleton
z Participantes:
p
{ 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 la
operacin 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
p
y la representacin.
p
Se p
puede
subclasificar de la clase Singleton y configurar la aplicacin con una
instancia de esta clase.
{ Fcil modificacin para permitir un nmero variable de instancias.
{ Ms flexible que las operaciones de clase.
17
Singleton
zImplementacin:
class Singleton {
p
private:
static Singleton* _instance;
void otherOperations();
protected:
Singleton();
public:
static Singleton* getInstance();
};
Singleton* Singleton::_instance = 0;
Singleton* Singleton::getInstance() {
if (_instance == 0 )
_instance
instance = new Singleton;
return _instance;
}
18
#include "stdafx.h"
#include <iostream>
using namespace std;
class Maze{
int x, y;
public:
M
Maze(int
(i x, iint y)) : x(x),
( ) y(y)
( ) {}
};
Ejemplo
class MazeFactory {
public:
bli
static MazeFactory* Instance();
// existing interface goes here
Maze * createMaze(int x, int y) { return new Maze(x, y); };
protected:
t t d
MazeFactory() {};
private:
static MazeFactory* _instance;
};
MazeFactory* MazeFactory::_instance = 0;
MazeFactory*
M
F t * MazeFactory::Instance
M
F t
I t
() {
if (_instance == 0) _instance = new MazeFactory;
return _instance;
}
void main(){
Maze * m = MazeFactory::Instance()->createMaze(10,10);
}
19
Singleton
z Implementacin:
{ Creacin de una subclase de singleton.
{ Determinar
D t
i
qu
singleton
i l t queremos usar en lla operacin
i I
Instance.
t
20
Singleton
z Dnde se registra la clase?
{ Una posibilidad es en el constructor.
MySingleton::MySingleton() {
// ...
Singleton::Register("MySingleton",
g
g
( y g
this);
)
}
21
Singleton
g
Ejemplo
class MazeFactory {
public:
static MazeFactory* Instance();
// existing
g interface g
goes here
protected:
MazeFactory();
private:
static MazeFactory
MazeFactory* _instance;
instance;
};
MazeFactory* MazeFactory::_instance = 0;
MazeFactory MazeFactory::Instance () {
MazeFactory*
if (_instance == 0) {
const char* mazeStyle = getenv("MAZESTYLE");
if (strcmp(mazeStyle, "bombed") == 0)
_instance
i t
= new B
BombedMazeFactory;
b dM
F t
} else if (strcmp(mazeStyle, "enchanted") == 0)
_instance = new EnchantedMazeFactory;
// ... other possible subclasses
} else
_instance = new MazeFactory;
return _instance;
}
22
Abstract Factory
z Propsito.
P
it
{ Proporciona una interfaz para crear familias de objetos
relacionados o que dependen entre s, sin especificar sus
clases
l
concretas.
z Motivacin.
{ Ej.: un framework para la construccin de interfaces de usuario
que permita varios look
and feel
f (ej.:
(
Motiff y Presentation
Manager).
z Una clase abstracta WidgetFactory con la interfaz para crear
cada tipo de widget.
widget
z Una clase abstracta para cada tipo de widget. Subclases
concretas que implementan cada widget concreto.
z De esta manera,
manera los clientes son independientes del look
and feel concreto.
23
Abstract Factory
z Motivacin.
WidgetFactory
CreateScrollBar()
CreateWindow()
Client
Productos
Window
Familias
MotifWindow
PMWindow
MotifWidgetFactory
CreateScrollBar()
CreateWindow()
PMWindowFactory
CreateScrollBar()
CreateWindow()
ScrollBar
PMScrollBar
MotifScrollBar
24
Abstract Factory
z Aplicabilidad. Usar este patrn cuando:
{un sistema que deba ser independiente de cmo se
crean, componen y representan sus productos.
d
{un sistema que deba ser configurado con una familia de
productos entre varias.
varias
{una familia de objetos producto relacionados que est
diseada para ser usada conjuntamente,
conjuntamente y es necesario
hacer cumplir esta restriccin.
quiere p
proporcionar
p
una biblioteca de clases
{se q
productos, y slo se quiere revelar sus interfaces, no su
implementacin.
25
Abstract Factory
zEstructura:
AbstractFactory
createProductA ()
createProductB ()
Client
Productos
AbstractProductA
Familias
ProductA2
ConcreteFactory1
ConcreteFactory2
createProductA ()
createProductB ()
createProductA ()
createProductB ()
ProductA1
AbstractProductB
ProductB2
ProductB1
26
Abstract Factory
z Participantes:
p
{ AbstractFactory. Declara una interfaz para operaciones que
crean objetos producto abstractos.
y Implementa
p
las operaciones
p
para crear objetos
p
j
{ ConcreteFactory.
producto concretos.
{ AbstractProduct. Declara una interfaz para un tipo de objeto
producto.
{ ConcreteProduct. Define un objeto producto para que sea creado
por la fbrica correspondiente.
{ Client. Slo usa interfaces declaradas por las clases
Ab t tF t
AbstractFactory
y AbstractProduct.
Ab t tP d t
z Colaboraciones.
{ Normalmente slo se crea una nica instancia de una clase
ConcreteFactory en tiempo de ejecucin. Esta fbrica concreta
crea
objetos
producto
que
tienen
una
determinada
implementacin.
{ AbstractFactory
Ab t tF t
d l
delega
l creacin
la
i de
d objetos
bj t
producto
d t en su
subclase ConcreteFactory.
27
Abstract Factory
zConsecuencias.
C
i
{Asla las clases concretas. Ayuda a controlar
las clases de objetos que crea una aplicacin.
Asla a los clientes de las clases de
implementacin.
implementacin
{Facilita el reemplazo de familias de productos.
{P
{Promueve
l consistencia
la
i t
i entre
t productos
d t (que
(
la aplicacin use objetos de una sola familia a
la vez).
vez)
{Es difcil aadir un nuevo producto.
28
Abstract Factory
Ejemplo
ttodos
d los
l componentes
t de
d la
l misma
i
marca (familia)
(f ili )
hay mltiples marcas (Ford, Toyota, Opel, ...)
es responsabilidad
p
del cliente ensamblar las p
piezas
Car
CarPart
FordCar
ToyotaEngine
PorscheCar
CarBody
CarEngine
FordEngine
ToyotaCar
PorscheEngine
FordBody
ToyotaBody
PorscheBody
29
Abstract Factory
Ejemplo (ii)
coche.add (motor);
...
return coche;
}
30
Abstract Factory
Ejemplo (iii)
CarPartFactory
makeCar ()
makeBody
y ()
makeEngine ()
Familias
ToyotaFactory
makeCar ()
makeBody ()
makeEngine ()
FordFactory
makeCar ()
makeBody ()
makeEngine ()
Client
Productos
CarBody
FordBody
ToyotaBody
CarEngine
FordEngine
ToyotaEngine
Car
FordCar
ToyotaCar
31
Abstract Factory
Ejemplo (iv)
Utilizando el patrn, ste fuerza a que todos los productos sean de la
misma familia, una vez establecida sta por el cliente.
En el cliente:
Car hacerCoche () {
Car coche=familia.makeCar();
coche.addEngine (familia.makeEngine());
coche.addBody (familia.makeBody ());
...
return
t
coche;
h
}
32
Abstract Factory
Ejemplo (v)
familia contiene una instancia de una marca de coche.
coche
Cmo se instancia familia?
class CrearCoche {
CarPartFactory
y * familia;;
//presenta por pantalla la seleccin
class CrearCocheGUI : public CFrameWnd {
//.
void
id O
OnButtonClicked
B tt Cli k d () {
string familiasel;
CrearCoche assembler;
Car coche;
//
//
if (familiasel == ford)
assembler=CrearCoche::using (new FordFactory())
else if (familiasel == toyota)
assembler=CrearCoche::using
bl C
C h
i ((new T
ToyotaFactory())
t F t ())
else ;
Car hacerCoche () {
Car coche=familia->makeCar();
coche.addEngine
g
((familia->makeEngine());
g ());
coche.addBody (familia->makeBody ());
...
return coche;
}
static CrearCoche using (CarPartFactory * f) {
CrearCoche l;
l.factory
y (f);
( );
return l;
}
coche = assembler.hacerCoche();
void factory
y (CarPartFactory
(
y * f)) {
familia=f;
}
}
}
}
33
Abstract Factory
Otro Ejemplo: Laberinto
MazeFactory
+MakeMaze(): Maze
+MakeWall(): Wall
+MakeRoom(int n): Room
+MakeDoor(Room r1, Room r2): Door
MazeGame
+CreateMaze(MazeFactory): Maze
Maze
Wall
Room
EnchantedMazeFactory
+MakeRoom(int n): EnchantedRoom
+MakeDoor(Room r1, Room r2):
DoorNeedingSpell
BombedMazeFactory
+MakeRoom(int n): RoomWithABomb
+MakeWall(): BombedWall
Bombed
Wall
Door
DoorNeeding
Spell
Enchanted
Room
RoomWithA
Bomb
34
Abstract Factory
Otro Ejemplo: Laberinto
class MazeFactory {
public:
MazeFactory();
virtual
it lM
Maze** M
MakeMaze()
k M
() constt
{ return new Maze; }
virtual Wall* MakeWall() const
{ return new Wall;; }
virtual Room* MakeRoom(int n) const
{ return new Room(n); }
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return
t
new Door(r1,
D ( 1 r2);
2) }
};
35
Abstract Factory
Otro Ejemplo
Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* aMaze = factory.MakeMaze();
Room* r1 = factory.MakeRoom(1);
Room
Room* r2 = factory.MakeRoom(2);
Door* aDoor = factory.MakeDoor(r1, r2);
aMaze->AddRoom(r1);
aMaze->AddRoom(r2);
M
AddR
( 2)
r1->SetSide(North, factory.MakeWall());
r1->SetSide(East, aDoor);
r1->SetSide(South,
(
, factory.MakeWall());
y
());
r1->SetSide(West, factory.MakeWall());
r2->SetSide(North, factory.MakeWall());
r2->SetSide(East, factory.MakeWall());
r2->SetSide(South,
2 >S tSid (S th factory.MakeWall());
f t
M k W ll())
r2->SetSide(West, aDoor);
return aMaze;
}
36
Abstract Factory
Otro Ejemplo
class EnchantedMazeFactory : public MazeFactory {
public:
EnchantedMazeFactory();
virtual Room* MakeRoom(int n) const
{ return new EnchantedRoom(n, CastSpell()); }
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return new DoorNeedingSpell(r1,
g p ( , r2);
);
}
protected:
Spell* CastSpell() const;
};
// Make it possible to have rooms with bombs
MazeGame game;
BombedMazeFactoryy factory;
y;
Wall* BombedMazeFactory::MakeWall () const {
Wall
game.CreateMaze(factory);
return new BombedWall;
}
Room* BombedMazeFactory::MakeRoom(int n) const {
return
t
new RoomWithABomb(n);
R
WithAB b( )
}
37
Factory Method
z Propsito.
P
it
{ Define una interfaz para crear un objeto, pero deja que
sean las subclases q
quienes decidan q
qu clase instanciar.
Permite que una clase delegue en sus subclases la
creacin de objetos.
z Motivacin.
{ Ej.: un framework que pueda presentar distintos tipos de
documentos (similar a MFCs).
z Dos abstracciones clave: aplicacin
p
y documento ((ambas
clases abstractas). Hay que subclasificarlas.
z La clase aplicacin no sabe qu subclase documento
instanciar.
38
Factory Method
z Motivacin.
Documento
+Abrir()
b ()
+Cerrar()
+Guardar()
+Deshacer()
docs
1..*
Aplicacion
+CrearDocumento()
CrearDocumento()
+NuevoDocumento()
+AbrirDocumento()
MiAplicacion
MiDocumento
+CrearDocumento()
C
D
t ()
39
Factory Method
z A
Aplicabilidad.
li bilid d Usar
U
este patrn
cuando:
d
{ Una clase no puede prever la clase de los objetos que tiene que crear.
{ Una clase quiere que sean sus subclases las que decidan qu objetos
crean.
{ Las clases delegan la responsabilidad en una de entre varias clases
auxiliares y queremos localizar qu subclase concreta es en la que se
auxiliares,
delega.
z Estructura.
Creator
P d t
Product
C
ConcreteProduct
t P d t
+FactoryMethod()
+AnOperation()
//
product = factoryMethod()
//
C
ConcreteCreator
t C t
+FactoryMethod()
40
Factory Method
z Participantes.
P ti i
t
{ Product (Documento). Define la interfaz de los objetos que crea
y method.
el factory
{ ConcreteProduct (MiDocumento). Implementa la interfaz del
producto.
{ Creator (Aplicacion).
(Aplicacion) Declara el factory method.
method Puede tambin
dar una implementacin por defecto del factory method, que
devuelve un objeto de una clase por defecto.
{ ConcreteCreator (MiAplicacion).
(MiAplicacion) Sobreescribe el factory
method para devolver una instancia de ConcreteProduct.
z Colaboraciones.
{ El creator se apoya en sus subclases para definir el mtodo de
fabricacin de manera que ste devuelva una instancia del
ConcreteProduct adecuado.
41
Factory Method
z Consecuencias
Consecuencias.
{Los mtodos de fabricacin eliminan la necesidad de
ligar
g clases especficas
p
de la aplicacin
p
a nuestro
cdigo.
{El cdigo slo trata con la interfaz Product,
Product puede
funcionar con cualquier clase ConcreteProduct
definida por el usuario.
{Proporciona enganches para las subclases. Crear
objetos con un mtodo de fabricacin es ms flexible
que hacerlos directamente.
{El factory
f t
method
th d es un hook
h k method
th d para que las
l
42
subclases den una versin extendida del cdigo.
Factory Method
zConsecuencias.
Figure
Manipulator
+CreateManipulator()
p
()
+DownClick()
+Drag()
g()
+UpClick()
LineFigure
TextFigure
+CreateManipulator()
+CreateManipulator()
LineManipulator
+DownClick()
+Drag()
+UpClick()
TextManipulator
+DownClick()
+Drag()
+UpClick()
43
Factory Method
zImplementacin.
I
l
t i
{Dos variantes principales:
z Cuando la clase Creator es abstracta y no
proporciona implementacin para el mtodo de
fabricacin que declara.
declara
zCuando la clase Creator es concreta y proporciona
una implementacin predeterminada para el mtodo
de fabricacin.
Factory Method
zImplementacin.
class Creator {
public:
Product* GetProduct();
protected:
virtual Product* CreateProduct(); // factory method
private:
Product* _product;
};
Product* Creator::GetProduct () {
if (_product
(
d t == 0) {
_product = CreateProduct();
}
ret rn _product;
return
prod ct
}
45
Factory Method
z Implementacin. Se pueden usar plantillas para evitar
la herencia (mltiples subclases de Creator).
class Creator {
public:
virtual Product* CreateProduct() = 0;
// pure virtual factory method
};
template <class TheProduct>
class StandardCreator: public Creator {
public:
virtual TheProduct* CreateProduct();
};
template <class TheProduct>
TheProduct*
StandardCreator<TheProduct>::CreateProduct () {
return new TheProduct;
}
46
Factory Method
Ejemplo
class MazeGame {
public:
Maze* CreateMaze();
();
// factory methods:
virtual Maze* MakeMaze() const
{ return new Maze; }
virtual Room* MakeRoom(int n) const
{ return new Room(n); }
virtual Wall* MakeWall() const
{ return new Wall; }
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return new Door(r1, r2); }
};
Maze* MazeGame::CreateMaze () {
Maze* aMaze = MakeMaze();
Room* r1 = MakeRoom(1);
Room
Room* r2 = MakeRoom(2);
Door* theDoor = MakeDoor(r1, r2);
aMaze->AddRoom(r1);
aMaze->AddRoom(r2);
M
AddR
( 2)
r1->SetSide(North, MakeWall());
r1->SetSide(East, theDoor);
r1->SetSide(South,
(
, MakeWall());
());
r1->SetSide(West, MakeWall());
r2->SetSide(North, MakeWall());
r2->SetSide(East, MakeWall());
r2->SetSide(South,
2 >S tSid (S th MakeWall());
M k W ll())
r2->SetSide(West, theDoor);
return aMaze;
}
47
Factory Method
Ejemplo
class BombedMazeGame : public MazeGame {
public:
BombedMazeGame();
virtual Wall*
Wall MakeWall() const
{ return new BombedWall; }
virtual Room* MakeRoom(int n) const
{ return new RoomWithABomb(n); }
};
class EnchantedMazeGame : public MazeGame {
public:
bli
EnchantedMazeGame();
virtual Room* MakeRoom(int n) const
{ return new EnchantedRoom(n,
( , CastSpell());
p ()); }
virtual Door* MakeDoor(Room* r1, Room* r2) const
{ return new DoorNeedingSpell(r1, r2); }
protected:
S ll* C
Spell*
CastSpell()
tS ll() const;
t
};
48
Indice
z Introduccin.
I t d
i
z Patrones de Creacin.
zPatrones
P t
E
Estructurales.
t
t
l
{Composite.
Co pos te
{Facade.
{Proxy.
{Pro
{Adapter.
z Patrones de Comportamiento.
z Conclusiones.
z Bibliografa.
49
Patrones Estructurales
z Establecen
E t bl
cmo
se componen clases
l
y objetos
bj t
para
formar
estructuras
mayores
que
implementan nueva funcionalidad.
funcionalidad
z Los patrones de clase usan la herencia para
componer interfaces o implementaciones (ej.:
(ej :
Adapter).
z Los patrones de objeto,
objeto describen maneras de
componer objetos para implementar nueva
funcionalidad.
funcionalidad
{ Flexibilidad, ya que se puede cambiar la configuracin
en tiempo de ejecucin.
50
Composite
z Propsito.
{ componer objetos en estructuras
representar jerarquas parte-conjunto.
arborescentes
para
z Motivacin.
M ti
i
{ Aplicaciones grficas. Manipulacin de grupos de figuras de
manera uniforme.
uniforme
Grafico
*
graficos
dibuja ()
Linea
Rectangulo
Texto
Dibujo
dibuja ()
dibuja ()
dibuja ()
dibuja ()
aade (Grafico g)
elimina (Grafico g)
obtenHijo (int)
Composite
z Una instancia en tiempo de ejecucin:
:Dibujo
graficos
graficos
:Dibujo
graficos
:Rectangulo
:Linea
graficos
:Texto
graficos
:Texto
Composite
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
objetos
j
y objetos
j
individuales. Los clientes tratarn todos los objetos
j
en
la estructura compuesta de manera uniforme.
z Estructura.
Client
Component
children
+ Operation()
+ Add(Component)
(
p
)
+ Remove(Component)
+ GetChild(int)
Leaf
Composite
+ Operation()
+ Operation()
p
()
+ Add(Component)
+ Remove(Component)
+ GetChild(int)
forall g in children:
g.Operation()
O
ti ()
53
Composite
z Participantes.
p
{ Component (Grafico).
z Declara la interfaz de los objetos de la composicin.
z Implementa
p
el comportamiento
p
por defecto de la interfaz comn a
p
todas 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 la estructura recursiva y la implementa,
implementa si es apropiado.
apropiado
{ Composite (Dibujo)
z Define el comportamiento de los objetos con hijos en la composicin.
z Almacena componentes hijo.
hijo
z Implementa operaciones relacionadas con los hijos de la interfaz de
Component.
{ Client.
Client
z Manipula objetos en la composicin a travs de la interfaz54 de
Component.
Composite
z Colaboraciones.
Colaboraciones
{ Los clientes usan el interfaz de la clase Component para
interaccionar con los objetos de la estructura compuesta.
{ Si ell objeto
bj t es hoja,
h j entonces
t
l peticin
la
ti i se cursa directamente.
di t
t
{ Si el objeto es un Composite, entonces normalmente redirige las
peticiones a sus objetos hijo, quiz realizando operaciones
adicionales antes y/o despus de la redireccin.
Composite
z Implementacin.
I l
t i Algunas
Al
d
decisiones:
i i
{ Referencias explcitas a los padres. En la clase component.
{ Compartir componentes. til para ahorrar memoria, pero la
gestin de un componente que tiene ms de un padre es difcil.
{ Maximizar la interfaz del componente.
{ Declaracin de las operaciones de gestin de hijos
hijos. Equilibrio
entre seguridad y transparencia:
z Declararla en la raz da transparencia. Es menos seguro porque el
cliente puede tratar de hacer cosas sin sentido sobre objetos hoja
hoja.
z Declararla en la clase compuesto da seguridad, pero perdemos
transparencia: leafs y composites tienen interfaces distintas.
Composite
Ejemplo
class Equipment {
public:
virtual ~Equipment();
const char* Name() { return _name; }
virtual
it lW
Watt
tt Power();
P
()
virtual Currency NetPrice();
virtual Currency DiscountPrice();
virtual void Add(Equipment*);
Add(Equipment );
virtual void Remove(Equipment*);
virtual Iterator* CreateIterator() {return 0;}
protected:
E i
Equipment(const
t(
t char*);
h *)
private:
const char* _name;
};
57
Composite
Ejemplo
class FloppyDisk : public Equipment {
public:
p
FloppyDisk(const char*);
virtual ~FloppyDisk();
virtual Watt Power();
virtual Currency NetPrice();
virtual Currency DiscountPrice();
};
class CompositeEquipment : public Equipment {
public:
virtual ~CompositeEquipment();
virtual Watt Power();
();
virtual Currency NetPrice();
virtual Currency DiscountPrice();
virtual void Add(Equipment*);
virtual void Remove(Equipment*);
virtual Iterator* CreateIterator();
protected:
CompositeEquipment(const
p
q p
(
char*);
)
private:
List _equipment;
};
58
Composite
Ejemplo
Currency CompositeEquipment::NetPrice () {
Iterator* i = CreateIterator();
Currency total = 0;
for (i->First();
(i >First(); !i->IsDone();
!i >IsDone(); ii->Next())
>Next()) {
total += i->CurrentItem()->NetPrice();
}
delete i;
return total;
}
class Chassis : public CompositeEquipment {
public:
Chassis(const char*);
virtual ~Chassis();
virtual
it lW
Watt
tt Power();
P
()
virtual Currency NetPrice();
virtual Currency DiscountPrice();
};
59
Composite
Ejemplo
60
Facade
z Propsito.
{ Proporciona
p
una interfaz unificada p
para un conjunto
j
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 objetivo tpico de diseo es minimizar la comunicacin y dependencias
entre subsistemas.
{ Un modo de conseguir esto es introducir un objeto fachada que
proporcione una interfaz nica y simplificada a los servicios ms generales
del subsistema.
61
Facade
z Motivacin.
62
Facade
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 de
sus clientes y otros subsistemas (mejora acoplamiento y portabilidad).
{ Queramos dividir en capas nuestros subsistemas. La fachada es el
punto de entrada a cada subsistema.
z Estructura.
E t
t
63
Facade
z Participantes.
Participantes
{ Facade (Compiler).
z Sabe qu clases del subsistema son las responsables ante una
peticin.
peticin
z Delega las peticiones de los clientes en los objetos apropiados del
subsistema.
z Observaciones.
{ Los clientes se comunican en el sistema enviando peticiones al
objeto Facade, que las reenva a los objetos apropiados.
{ Los clientes que usan la fachada no tienen que acceder
directamente a los objetos del subsistema.
64
Facade
z Consecuencias.
C
i
{ Oculta a los clientes los componentes del sistema, haciendo
el sistema ms fcil de usar.
{ Promueve acoplamiento dbil entre el subsistema y sus
clientes.
z Elimina dependencias
compilacin.
puede
reducir
el
tiempo
de
Facade
Ejemplo: Una fachada para un sistema de compilacin
class Scanner {
public:
Scanner(istream&);
virtual ~Scanner();
virtual
it lT
Token&
k &S
Scan();
()
private:
istream& _inputStream;
};
class Parser {
public:
Parser();
virtual ~Parser();
virtual void Parse(Scanner&, ProgramNodeBuilder&);
}
};
66
Facade
Ejemplo: Una fachada para un sistema de compilacin
class ProgramNodeBuilder
g
{
public:
ProgramNodeBuilder();
virtual ProgramNode* NewVariable
virtual ProgramNode* NewAssignment
67
Facade
Ej
Ejemplo:
l Una
U ffachada
h d para un sistema
i t
de
d compilacin
il i
class ProgramNode {
public:
// program node manipulation
virtual void GetSourcePosition(int& line, int& index);
// ...
// child manipulation
virtual void Add(ProgramNode*);
virtual void Remove(ProgramNode*);
// ...
virtual void Traverse(CodeGenerator&);
protected:
ProgramNode();
};
class CodeGenerator {
public:
virtual void Visit(StatementNode*);
virtual
i t l void
id Vi
Visit(ExpressionNode*);
it(E
i N d *)
// ...
protected:
CodeGenerator(BytecodeStream&);
CodeGe
e a o ( y ecodeS ea &);
protected:
BytecodeStream& _output;
};
68
Facade
Ejemplo: Una fachada para un sistema de compilacin
void ExpressionNode::Traverse (CodeGenerator& cg) {
cg.Visit(this);
Vi it(thi )
ListIterator i(_children);
for (i.First(); !i.IsDone(); i.Next()) {
i.CurrentItem()->Traverse(cg);
()
( g);
}
}
class Compiler { // Clase Facade
public:
bli
Compiler();
virtual void Compile(istream&, BytecodeStream&);
};
void Compiler::Compile ( istream& input, BytecodeStream& output ) {
Scanner scanner(input);
P
ProgramNodeBuilder
N d B ild b
builder;
ild
Parser parser;
parser.Parse(scanner, builder);
generator(output);
( p );
RISCCodeGenerator g
ProgramNode* parseTree = builder.GetRootNode();
parseTree->Traverse(generator);
}
69
Proxy
z Propsito.
Propsito
{ Proporcionar un representante o substituto de otro objeto
para controlar el acceso a este.
z Motivacin.
M ti
i
{ Retrasar el coste de creacin e inicializacin de un objeto
que sea realmente necesario.
hasta q
{ Ej.: al abrir un documento, no abrir las imgenes que no sean
visibles.
aTextDocument:
image
anImageProxy:
fileName
anImage:
data
70
en memoria
en disco
Proxy
zMotivacin.
71
Proxy
z Aplicabilidad.
Aplicabilidad
{ 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.:
I
ImageProxy).
P
)
{ 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 Contar
C t ell nmero
d referencias.
de
f
i
z Cargar un objeto persistente en memoria.
z Bloquear el objeto cuando se accede a l (no modificacin
concurrente)
concurrente).
z
72
Proxy
z Estructura.
73
Proxy
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 Remoto: codifican las peticiones
peticiones, y se las mandan al sujeto
sujeto.
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
realizar la peticin
peticin.
{ Subject.
z Define una interfaz comn para el RealSubject y el Proxy, de tal
manera que el Proxy se puede usan en vez del RealSubject
RealSubject.
{ RealSubject.
z Define el objeto real que el proxy representa.
z Colaboraciones.
Colaboraciones
{ El proxy redirige peticiones al sujeto real cuando sea necesario,74
dependiendo del tipo de proxy.
Proxy
z Consecuencias.
Consecuencias
{ Introduce un nivel de indireccin adicional, que tiene muchos
posibles usos:
z Un
U proxy remoto
t puede
d ocultar
lt ell h
hecho
h d
de que un objeto
bj t reside
id en
otro espacio de direcciones.
z Un proxy virtual puede realizar optimizaciones, como crear objetos
bajo demanda
demanda.
z Tanto los proxies de proteccin, como las referencias inteligentes
permiten realizar tareas de mantenimiento adicionales cuando se
accede a un objeto
objeto.
75
Proxy
z Implementacin
Implementacin.
{ Se pueden explotar las
siguientes caractersticas de
l lenguajes:
los
l
j
z Sobrecargar el operador de
acceso a miembros -> en
C++
C++.
class Image;
extern Image* LoadAnImageFile(const char*);
// external function
class ImagePtr {
public:
ImagePtr(const char*
char imageFile);
virtual ~ImagePtr();
virtual Image* operator->();
virtual Image& operator*();
private:
Image* LoadImage();
private:
Image* _image;
Image
image;
const char* _imageFile;
};
ImagePtr::ImagePtr (const char* theImageFile) {
_imageFile = theImageFile;
_image = 0;
}
Image* ImagePtr::LoadImage () {
Image
if (_image == 0) {
_image = LoadAnImageFile(_imageFile);
}
return _image;
76
}
Proxy
Image ImagePtr::operator
Image*
ImagePtr::operator-> () {
return LoadImage();
}
Image& ImagePtr::operator* () {
return
t
*LoadImage();
*L dI
()
}
ImagePtr image = ImagePtr("anImageFileName");
image->Draw(Point(50, 100));
// (image.operator->())->Draw(Point(50, 100))
Proxy
Ejemplo: Un Proxy Virtual
class Graphic {
public:
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;
p
protected:
Graphic();
};
class Image : public Graphic {
public:
Image(const char* file); // loads image from a file
virtual ~Image();
virtual void Draw(const Point& at);
virtual void HandleMouse(Event& event);
virtual const Point& GetExtent();
virtual void Load(istream& from);
virtual void Save(ostream& to);
private:
// ...
};
78
Proxy
Ejemplo: Un Proxy Virtual
class ImageProxy : public Graphic { // la clase proxy
public:
ImageProxy(const char* imageFile);
virtual ~ImageProxy();
virtual
i t l void
id D
Draw(const
(
t Point&
P i t& at);
t)
virtual void HandleMouse(Event& event);
virtual const Point& GetExtent();
virtual void Load(istream& from);
virtual void Save(ostream& to);
protected:
Image* GetImage();
private:
i t
Image* _image;
Point _extent;
cchar*
a _fileName;
e a e;
};
79
Proxy
Ejemplo: Un Proxy Virtual
ImageProxy::ImageProxy (const char
char* fileName) {
_fileName = strdup(fileName);
_extent = Point::Zero; // don't know extent yet
_image = 0;
}
Image* ImageProxy::GetImage() {
if (_image == 0) {
_image = new Image(_fileName);
}
return _image;
}
Proxy
Ejemplo: Un Proxy Virtual
class TextDocument {
public:
TextDocument();
void Insert(Graphic*);
// ...
};
TextDocument* text = new TextDocument;
// ...
text->Insert(new ImageProxy("anImageFileName"));
81
Ejercicio
z En el contexto de la aplicacin anterior, supn
que slo se puede acceder al disponible de una
cuenta de pago si se ha introducido una clave.
Utilizando patrones de diseo, implementa en
C++ un Proxy de Proteccin que asegure que se
accede al disponible de la cuenta slo si la clave
es correcta (supn que la clave se pide por la
consola). La clave se almacena en el proxy, y
ste recuerda si ya se ha introducido
correctamente o no.
Solucin (1)
#include "stdafx.h"
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::cin;
class Cuenta
{
public:
virtual int obtenerDisponible () = 0;
};
class CuentaReal : public Cuenta
{
private:
int disponible;
public:
CuentaReal (int d ) : disponible (d) {}
int obtenerDisponible() {return disponible; }
};
class ProxyCuenta: public Cuenta
{
private:
CuentaReal * cuenta;
string clave;
bool correcta;
bool intro;
public:
ProxyCuenta ( string psswd,
psswd CuentaReal & c ) :
clave(psswd), cuenta(&c), intro(false), correcta(false) {}
int obtenerDisponible();
};
Solucin (2)
int ProxyCuenta::obtenerDisponible() {
if (correcta) return cuenta->obtenerDisponible();
else if (!intro) {
intro = true;
string cl;
cout << "Introduce la clave:\n";
cin >> cl;
if (cl == clave) {
correcta = true;
return cuenta->obtenerDisponible();
}
else {
correcta = false;
cout << "clave incorrecta\n";
return -1;
}
}
return -1;
}
void main()
{
CuentaReal c (100);
ProxyCuenta pc ("clave1", c);
int d = pc.obtenerDisponible();
cout << "Disponible = " << d << "\n";
cout << "Disponible = " << pc.obtenerDisponible();
}
Adapter
z Propsito.
{ Convierte el interfaz de una clase en otro q
que espera
p
el cliente.
{ El adapter permite trabajar juntas a clases que de otra forma no podran por
tener interfaces incompatibles.
z Motivacin.
{ A veces una clase de una biblioteca que ha sido diseada para reutilizarse
reutilizarse,
no puede hacerlo porque su interfaz no coincide con la interfaz especfica
de dominio que requiere la aplicacin.
{ Ej.:
Ej : un editor de dibujo
dibujo. Objetos grficos
grficos, con una clase base abstracta
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 a
Shape.
z Se puede hacer de dos maneras:
Adaptador de clase: Heredando el interfaz de Shape y la implementacin de
TextView.
Adaptador de objeto: Componiendo un objeto TextView dentro de un TextShape,86e
implementando TextShape en trminos de la interfaz de TextView.
Adapter
zMotivacin.
{ Adaptador
p
de objeto.
j
87
Adapter
zEstructura.
{Adaptador
p
de clase.
88
Adapter
zEstructura.
{Adaptador
p
de objeto.
j
89
Indice
z Introduccin.
z Patrones de Creacin.
z Patrones Estructurales.
zPatrones de Comportamiento
Comportamiento.
{Iterator.
{Observer.
{Template Method.
{State.
gy
{Strategy.
{Command.
{Chain of Responsibility.
Responsibility
z Conclusiones.
z Bibliografa.
90
Patrones de Comportamiento
zTratan sobre algoritmos y la asignacin de
p
entre objetos.
j
responsabilidades
zDescriben no slo patrones de clases y
objetos sino patrones de comunicacin
objetos,
entre ellos.
zCaracterizan un flujo de control complejo,
difcil de seguir en tiempo de ejecucin.
zPermiten que el diseador se concentre
slo
l en cmo
iinterconectar
t
t objetos.
bj t
Iterator
z Propsito.
Propsito
{ Proporciona un medio de acceder a los elementos de un
contenedor secuencialmente sin exponer su representacin
interna.
interna
z Motivacin.
{ Un contenedor (p.ej.: una lista) debe proporcionar un medio de
g sus datos secuencialmente sin exponer
p
su
navegar
representacin 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 para
realizar los diferentes recorridos.
{ Puede necesitarse hacer ms de un recorrido simultneamente.
{ Dar la responsabilidad de acceder y recorrer el objeto lista a un
92
objeto Iterator.
Iterator
z Motivacin.
list
List
1
+ Count()
+ Append(Element)
+ Remove(Element)
ListIterator
- index
+ First()
+ Next()
+ IsDone()
+ CurrentItem()
Iterator
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: iteracin
polimrfica.
AbstractList
+CreateIterator()
+ Count()
+ Append(Element)
A
d(El
t)
+ Remove(Element)
1
skiplist
SkipList
List
1 list
Cli t
Client
Iterator
+ First()
+ Next()
+ IsDone()
+ CurrentItem()
ListIterator
SkipListIterator *
{ Podemos hacer responsables a las listas de crear sus propios iteradores, mediante un factory
method (CreateIterator).
94
{ Se puede definir algoritmos generales que usan un iterador genrico (en C++: for_each, find_if,
count, etc)
Iterator
z Aplicabilidad. Usar el patrn :
{ para acceder al contenido de un contenedor sin exponer su
representacin interna.
{ para permitir varios recorridos sobre contenedores.
{ para proporcionar una interfaz uniforme para recorres distintos tipos
de contenedores (esto es, permitir la iteracin polimrfica).
z Estructura.
Aggregate
+CreateIterator ()
Iterator
Client
+First ()
+Next ()
+IsDone
IsDone ()
+CurrentItem ()
ConcreteAggregate
+CreateIterator ()
ConcreteIterator
95
Iterator
z Participantes.
Participantes
{ 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 ConcreteIterator sabe cul es el objeto actual del agregado y
puede calcular el objeto siguiente del recorrido.
96
Iterator
z Consecuencias.
Consecuencias
{ 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.
z Implementacin.
{ Quin controla la iteracin?.
z El cliente controla la iteracin: iterador externo.
z El iterador controla la iteracin: iterador interno.
interno
Iterator
z Implementacin.
I l
t i
{ Operaciones adicionales del iterador.
z Por ejemplo, iteradores ordenados podran tener una operacin
Previous. Otras como SkipTo.
{ NullIterators.
z Es un iterador degenerado
g
q
que ayuda
y
a manejar
j condiciones
lmite.
98
Iterator
Ejemplo
1 Interfaces de la lista y el iterador
1.
iterador.
template <class Item>
class List {
public:
List(long size = DEFAULT_LIST_CAPACITY);
long Count() const;
Item& Get(long index) const;
// ...
};
template <class Item>
class Iterator {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
protected:
Iterator();
};
99
Iterator
Ejemplo
2 Implementaciones de las subclases del iterador
2.
iterador.
template <class Item>
class ListIterator : public Iterator<Item> {
public:
ListIterator(const List<Item>* 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:
const List<Item>*
List<Item> _list;
list;
long _current;
};
template <class Item>
Item ListIterator<Item>::CurrentItem () const {
if (IsDone()) throw IteratorOutOfBounds;
return _list->Get(_current);
}
// Se puede implementar un ReverseListIterator, con First
// posicionando el iterador al final de la lista, y Next decrementando
100
Iterator
Ejemplo
3 U
3.
Uso d
dell iiterador.
d
void PrintEmployees (Iterator<Employee*>& i) {
for ((i.First();
(); !i.IsDone();
(); i.Next())
()) {
i.CurrentItem()->Print();
}
}
List<Employee*>* employees;
// ...
ListIterator<Employee*> forward(employees);
ReverseListIterator<Employee*> backward(employees);
PrintEmployees(forward);
PrintEmployees(backward);
101
Iterator
Ejemplo
4. Evitar ajustarse
j
a una implementacin
p
concreta de la lista.
{ Supongamos que tenemos SkipList y SkipListIterator.
{ Se puede introducir un AbstractList para estandarizar la interfaz de la lista
((List y SkipList
p
son subclases de AbstractList).
)
{ Para permitir iteracin polimrfica, AbstractList define un factory method
CreateIterator.
template <class Item>
class AbstractList {
public:
virtual Iterator<Item>* CreateIterator() const = 0;
// ...
};
102
Iterator
Ejemplo
5. Asegurarse
g
de que
q 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 Item>
class IteratorPtr {
public:
IteratorPtr(Iterator<Item>* i): _i(i)
i(i) { }
~IteratorPtr() { delete _i; }
Iterator<Item>* operator->() { return _i; }
Iterator<Item>& operator*()
p
() { return *_i;
_ }
private:
// disallow copy and assignment to avoid
// multiple deletions of _i:
IteratorPtr(const IteratorPtr&);
IteratorPtr& operator=(const IteratorPtr&);
private:
Iterator<Item>* _
_i;
};
AbstractList<Employee*>* employees;
// ...
I
IteratorPtr<Employee*>
P E l
*
iterator(employees->CreateIterator());
PrintEmployees(*iterator);
103
Iterator
Ejemplo
6. Un iterador interno.
{ El iterador controla la iteracin, y aplica una operacin a cada elemento.
{ La operacin se puede configurar:
z Pasando un puntero a una funcin
funcin, o a un objeto funcin
funcin.
z Mediante subclasificacin.
template <class Item>
template <class Item>
class ListTraverser {
bool ListTraverser<Item>::Traverse () {
public:
bool result = false;
ListTraverser(List<Item>* aList):_iterator(aList) { };
for ( _iterator.First();
iterator First(); !!_iterator.IsDone();_iterator.Next())
iterator IsDone(); iterator Next()) {
bool Traverse();
result = ProcessItem(_iterator.CurrentItem());
protected:
if (result == false) break;
virtual bool ProcessItem(const Item&) = 0;
}
private:
return result;
ListIterator<Item> _iterator;
}
};
104
Iterator
Ejemplo
6 U
6.
Un iiterador
d iinterno
{ Imprimir los n primeros empleados de una lista.
class PrintNEmployees : public ListTraverser<Employee*> {
public:
PrintNEmployees(List<Employee*>* aList, int n) :
ListTraverser<Employee*>(aList),
p y
(
)
_total(n), _count(0) { }
protected:
bool ProcessItem(Employee* const&);
private:
int _total;
int _count;
}
};
bool PrintNEmployees::ProcessItem (Employee* const& e) {
_count++;
e >Print();
e->Print();
return _count < _total;
}
105
Iterator
Ejemplo
6 U
6.
Un it
iterador
d iinterno
t
{ Imprimir los n primeros empleados de una lista.
List Employee
List<Employee*>*
employees;
// ...
PrintNEmployees pa(employees, 10);
pa.Traverse();
106
Iterator
Ejemplo
6 U
6.
Un iiterador
d iinterno
{ Pueden encapsular distintos tipos de operaciones.
template <class Item>
template <class Item>
class FilteringListTraverser {
void FilteringListTraverser<Item>::Traverse () {
public:
bool result = false;
FilteringListTraverser(List<Item>* aList);
for (_
(_iterator.First();!_iterator.IsDone();_iterator.Next())
() _
() _
()) {
bool Traverse();
()
if (TestItem(_iterator.CurrentItem())) {
protected:
result = ProcessItem(_iterator.CurrentItem());
virtual bool ProcessItem(const Item&) = 0;
if (result == false) break;
virtual bool TestItem(const
(
Item&)) = 0;
}
private:
}
ListIterator<Item> _iterator;
return result;
};
}
107
Observer
z Propsito.
P
it
{ Define una dependencia de uno-a-muchos entre objetos, de
que cuando un objeto
j
cambie de estado se notifique
q y
forma q
actualicen automticamente todos los objetos que dependen
de l.
z Motivacin.
{ Mantener consistencia entre objetos relacionados.
{ No queremos obtener dicha consistencia aumentando el
acoplamiento entre clases.
clases
{ Ej.: separacin de la presentacin en GUI de los datos de
aplicacin subyacente.
108
Observer
z Motivacin.
40
60
20
15
40
25
15
20
10
10
10
20
60
D
A
30
20
Modelo
A:
B:
C
C:
D:
40%
25%
15%
20%
109
Observer
z Aplicabilidad.
{ Cuando una abstraccin tiene dos aspectos y uno depende del otro.
{ Cuando un cambio en un objeto requiere cambiar otros, y no sabemos
cuntos hayy q
que cambiar.
{ Cuando un objeto debera ser capaz de notificar a otros sin hacer
suposiciones sobre quines son dichos objetos (esto es, no queremos
que los objetos estn fuertemente acoplados).
acoplados)
z Estructura.
Subject
+Attach (Observer)
+Detach (Observer)
+Notify ()
observers
0 1
0..1
1 *
1..*
Observer
+Update()
forall o in observers
o.Update()
ConcreteObserver
ConcreteSubject
0..1
subject
- subjectState
+GetState ()
+SetState ()
return subjectState
- observerState
+Update ()
observerState=
subject->GetState()
110
Observer
z Participantes.
{ Subject.
S bj t
z Conoce a sus observadores, que pueden ser un nmero arbitrario.
z Proporciona un interfaz para aadir y quitar objetos Observer.
{ Observer.
Ob
z Define un interfaz de actualizacin para los objetos que deben ser
notificados sobre cambios en un sujeto.
{ ConcreteSubject.
ConcreteSubject
z Almacena estado de inters para ConcreteObservers.
z Manda notificaciones a sus observadores cuando su estado cambia.
{ ConcreteObserver.
ConcreteObserver
z Mantiene una referencia a objetos ConcreteSubject.
z Almacena el estado que debe ser consistente con el del sujeto.
z Implementa el interfaz de actualizacin del Observer para mantener su
estado consistente con el del sujeto.
111
Observer
z Colaboraciones.
{ El ConcreteSubject notifica a sus observadores cada vez que se
produce un cambio que pudiera hacer que el estado de estos fuese
inconsistente con el suyo.
y
{ Despus de ser notificado del cambio, un ConcreteObserver puede
pedir al subject ms informacin.
barDiagram
:ConcreteObserver
:ConcreteSubject
sectorDiagram
:ConcreteObserver
SetState()
Notify()
Update()
GetState()
Update()
GetState()
112
Observer
z Consecuencias.
Consecuencias
{ Permite modificar los sujetos y observadores de manera
independiente.
{ Se
S pueden
d
reutilizar
tili
l
los
sujetos
j t
sin
i sus observadores
b
d
y
viceversa.
{ Se pueden aadir observadores sin modificar el sujeto u otros
observadores.
observadores
{ Acoplamiento abstracto entre sujeto y observador. El sujeto no
conoce la clase concreta de ningn observador (el acoplamiento
es mnimo).
mnimo)
{ Capacidad de comunicacin mediante difusin. La notificacin
del sujeto se enva automticamente a todos los observadores
pueden aadir y q
quitar observadores en cualquier
q
suscritos. Se p
momento.
{ Actualizaciones inesperadas. Una operacin aparentemente
inofensiva sobre el sujeto puede desencadenar una cascada de
cambios
bi en los
l observadores.
b
d
113
Observer
z Implementacin.
Implementacin
{ Correspondencia entre sujetos y observadores.
z Que el sujeto guarde referencias a los observadores a los que debe
notificar.
notificar
{ Observar ms de un sujeto.
z Ej.: una hoja de clculo puede observar ms de un origen de datos.
z Extender la interfaz de actualizacin para que el observador sepa
qu sujeto se ha actualizado (quiz simplemente el sujeto se pase
a s mismo como parmetro del update()).
{ Q
Quin dispara
p
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.
Observer
z Implementacin.
{Referencias perdidas a sujetos borrados.
z Una manera de evitarlo es notificar a los observadores
cuando se borra un sujeto.
Observer
z Implementacin.
Implementacin
{ Evitar protocolos especficos del obervador: los modelos
push y pull.
z Las implementaciones de observer suelen hacer que el sujeto
envie informacin adicional como parmetro de Update().
z Dos extremos:
Modelo Push: el sujeto enva informacin detalla del cambio
cambio, quieran
los observadores o no.
Inconveniente: observadores menos reutilizables.
Modelo Pull: el sujeto no enva nada, y los observadores piden
d
despus
llos d
detalles
t ll explcitamente.
l it
t
Inconveniente: puede ser poco eficiente.
Observer
z Implementacin.
{ Encapsular la semntica de las operaciones complejas
complejas.
z Si la relacin de dependencia entre sujetos y observadores es compleja, puede ser
necesario un objeto intermedio para la gestin de cambios (ChangeManager).
z Minimizar el trabajo
j necesario p
para q
que los observadores reflejen
j 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
subjects
0..*
+Attach (Observer o)
+Detach (Observer)
+Notify ()
chman
observers
ChangeManager
Subject-Observer mapping
+Register (Subject,Observer)
+Unregister (Subject,Observer)
+Notify ()
chman->Notify()
chman
>Notify()
Observer
1..*
+Update(Subject)
Marcar todos los observers
a actualizar.
Actualizar los observers
marcados.
chman->Registar(this,o)
forall s in subjects:
forall o in observers:
o->Update(s)
SimpleChangeManager
DAGChangeManager
+Register (Subject,Observer)
+Unregister (Subject,Observer)
+Notify ()
+Register (Subject,Observer)
+Unregister (Subject,Observer)
+Notify ()
117
Observer
Ejemplo
class Subject;
class Observer {
public:
virtual ~ Observer();
()
virtual void Update (Subject*
theChangedSubject) = 0;
// soporte de mltiples subjects
protected:
Observer();
};
class Subject {
public:
virtual ~Subject();
j ()
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
private:
List<Observer*> *_observers;
_
};
void Subject::Attach (Observer* o) {
_observers->Append(o);
}
void Subject::Detach (Observer* o) {
_observers->Remove(o);
}
void Subject::Notify () {
ListIterator<Observer*> i(_observers);
for (i.First(); !i.IsDone(); i.Next()) {
i CurrentItem() >Update(this);
i.CurrentItem()->Update(this);
}
118
}
Observer
Ejemplo
class ClockTimer : public Subject {
// Concrete subject
public:
ClockTimer();
()
virtual int GetHour();
virtual int GetMinute();
virtual int GetSecond();
void Tick();
};
void ClockTimer::Tick () {
// update internal time-keeping state
// ...
Notify();
}
119
Observer
Ejemplo
void DigitalClock::Update (Subject* theChangedSubject) {
if (theChangedSubject == _subject) Draw();
}
void DigitalClock::Draw () {
int hour = _subject->GetHour(); // get the new values from the subject
int minute = _subject->GetMinute();
// etc.
// draw the digital clock
}
class AnalogClock : public Widget
Widget, public Observer {
public:
AnalogClock(ClockTimer*);
virtual void Update(Subject*);
virtual void Draw();
// ...
};
ClockTimer* timer = new ClockTimer;
AnalogClock* analogClock = new AnalogClock(timer);
DigitalClock* digitalClock = new DigitalClock(timer);
120
Observer
Usos Conocidos
121
Template Method
z Propsito.
p
{ Definir el esqueleto de un algoritmo, delegando en las subclases
alguno de sus pasos.
{ Permite que las subclases cambien pasos de un algoritmo sin cambiar
su estructura.
z Motivacin.
{ Ej.: MFCs, abrir un fichero.
Document
docs
1 *
1..*
+Abrir()
+Cerrar()
+Guardar()
+DoRead()
D R d()
MyDocument
y
+DoRead()
return MyDocument
Application
pp
+AddDocument()
+OpenDocument()
+DoCreateDocument()
+CanOpenDocument()
+AboutToOpenDocument()
MyApplication
+DoCreateDocument()
+CanOpenDocument()
+AboutToOpenDocument()
Template Method
z Aplicabilidad.
{ Para implementar las partes de un algoritmo que no cambian,
y dejar que las subclases implementen el comportamiento
que puede variar
variar.
{ Cuando el comportamiento repetido de varias subclases
debera factorizarse y localizarse en una clase comn, para
evitar cdigo duplicado.
{ Para controlar las extensiones de las subclases.
z Estructura.
E t
t
ClaseAbstracta
+TemplateMethod()
+PrimitiveOperation1()
+PrimitiveOperation2()
+
PrimitiveOperation1()
PrimitiveOperation2()
ConcreteClass
+PrimitiveOperation1()
+PrimitiveOperation2()
123
State
z Propsito.
{ Permitir que un objeto modifique su comportamiento cada vez que cambie su
estado interno.
{ Parecer que cambia la clase del objeto.
z Motivacin.
{ TCPConnection p
para representar
p
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
State
zEstructura.
125
Strategy
z Propsito.
{ Define una familia de algoritmos, encapsula cada uno de ellos, y los hace
intercambiables.
{ Permite que un algoritmo vare independientemente de los clientes que los usan.
z Motivacin.
Motivacin
{ Ej.: Algoritmos para dividir en lneas un flujo de texto.
{ Clases que encapsulen los distintos algoritmos de divisin. Un algoritmo as
encapsulado se denomina estrategia.
estrategia
126
Strategy
zEstructura.
127
Command
z Propsito.
{ Encapsula peticiones a objetos
objetos.
{ Permite parametrizar a los clientes con diferentes peticiones, hacer
cola o llevar un registro de peticiones, as como deshacer las
peticiones.
peticiones
z Tambin conocido como.
{ Action, Transaction.
z Motivacin.
M ti
i
{ Framework grfico tipo MFC. Peticiones de los distintos widgets
encapsuladas como objetos.
128
Command
z Motivacin.
M ti
i
129
Command
z Estructura.
E t
t
130
Chain of Resposibility
z Propsito.
{ Evita acoplar el emisor de una peticin a su receptor, dando a ms
de un objeto la posibilidad de responder a la peticin.
{ Encadena los objetos receptores y pasa la peticin a travs de la
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 ayuda
para una p
p
parte ms g
general.
131
Chain of Resposibility
zMotivacin.
132
Chain of Resposibility
zEstructura.
133
Indice
z
z
z
z
IIntroduccin.
t d
i
Patrones de Creacin.
Patrones Estructurales.
Estructurales
Patrones de Comportamiento.
zConclusiones.
zConclusiones
z Bibliografa.
134
Conclusiones
z Los patrones de diseo capturan el conocimiento que
tienen los expertos a la hora de disear.
z Los patrones ayudan a generar software maleable
(software que soporta y facilita el cambio, la reutilizacin
y la mejora).
mejora)
z Los patrones de diseo son guas, no reglas rigurosas.
z Cada patrn describe la solucin a problemas que se
repiten una y orta vez en nuestro entorno,
entorno de forma que
se puede usar esa solucin todas las veces que haga
falta.
135
Indice
z
z
z
z
z
IIntroduccin.
t d
i
Patrones de Creacin.
Patrones Estructurales.
Estructurales
Patrones de Comportamiento.
Conclusiones
Conclusiones.
zBibliografa.
136
Bibliografa
z Design
D i patterns,
tt
elements
l
t off reusable
bl objectbj t
oriented software. Gamma, Helm, Jonhnson,
Vlissides Addison Wesley,
Vlissides.
Wesley 1995 (traducido al
espaol en 2003).
z Applying UML and Patterns. An introduction to
Object Oriented Analysis and Design and
Object-Oriented
Iterative Development. 3rd Edition. Craig
Larman Prentice Hall
Larman.
Hall.2005.
2005
z http://hillside.net/
http://hillside net/
137