8_patrones.pdf

137
Patrones de Diseño Tema 7 TACC II Grupo 46 1 TACC II Curso 2008/09

Upload: lina-johanna-garcia-mantilla

Post on 25-Nov-2015

15 views

Category:

Documents


1 download

TRANSCRIPT

  • Patrones de DiseoTema 7

    TACC II

    Grupo 46

    111

    TACC IICurso 2008/09

  • IndiceIndice

    I t d iz Introduccin.{ 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.z C l iz Conclusiones.z Bibliografa.

    222

  • IntroduccinIntroduccin

    z Di fi l bl lz Diseo especfico para el problema, pero general 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

  • PatrnPatrn

    z Un esquema que se usa para solucionar un problemaz Un esquema que se usa para solucionar un problema.

    z El esquema ha sido probado extensivamente, y haz El esquema ha sido probado extensivamente, y ha funcionado. Se tiene experiencia sobre su uso.

    z E i t h d i iz Existen en muchos dominios:{ Novelas y el cine: hroe trgico, comedia romntica, etc.{ Arte.{ Ingenieras.{ Arquitectura. z Christopher Alexander. A Pattern Language: Towns, Buildings, p g g , g ,

    Construction. 1977.z http://www.patternlanguage.com

    4

  • Patrones de DiseoPatrones de Diseo

    z R tili di b t t i l d t llz Reutilizar diseos abstractos que no incluyan detalles de la implementacin.

    z Un patrn es una descripcin del problema y la esencia de su solucin, que se puede reutilizar en casos q pdistintos.

    E l i d d bl z Es una solucin adecuada a un problema comn.

    z A i d i t i bj t l i i iz Asociado a orientacin a objetos, pero el principio general es aplicable a todos los enfoques de diseo software.

    5

  • Patrones de Diseo

    z D t l i i l di

    Patrones de Diseo

    z Documentar la experiencia en el 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 cmo se com nican los objetos{ De comportamiento: cmo se comunican los objetos, cooperan y distribuyen las responsabilidades para lograr sus objetivos.

    6

  • Patrones de DiseoEstructura de un patrn

    z N b d l t z Nombre del patrn.{ Describe el problema de diseo, junto con sus soluciones y

    consecuencias. { V b l i d di { Vocabulario de diseo.

    z Problema.{ Describe cundo aplicar el patrn. { Explica el problema y su contexto.

    z Solucin.{ Elementos que forman el diseo, relaciones, responsabilidades.{ Elementos que forman el diseo, relaciones, responsabilidades.{ No un diseo concreto, sino una plantilla que puede aplicarse en

    muchas situaciones distintas.z Consecuenciasz Consecuencias.{ Resultados, ventajas e inconvenientes de aplicar el patrn.{ P.ej.: relacin entre eficiencia en espacio y tiempo; cuestiones de

    implementacin etc7

    implementacin, etc.

  • Patrones de DiseoEjemplo: MVC de Smalltalk

    zModelo/Vista/Controlador.40

    A

    C

    D

    10

    20

    30

    40

    A B C DX 60 20 15 5Y 40 25 15 20

    B 0A B C D

    Y 40 25 15 20Z 10 10 20 60

    ModeloA: 40%B: 25%C 15%

    8

    C: 15%D: 20%

  • Patrones de Diseo

    z S l bj t l d t ( d l )Ejemplo: MVC de Smalltalk

    z Separar los objetos con los datos (modelo), sus visualizaciones (vistas) y el modo en que la interfaz reacciona ante la entrada al usuario (controlador).( )

    z Separar estos componentes, para aumentar la p p pflexibilidad y reutilizacin.

    D l i d d l di l dz Desacoplar vistas de modelos, mediante un protocolo de subscripcin/notificacin.

    z Cada vez que cambian los datos del modelo, avisar a las vistas que dependen de l. Estas se actualizan.

    9

    q p

  • Patrones de Diseo

    z Patrn Observer ms general (dependencias entreEjemplo: MVC de Smalltalk

    z Patrn Observer, ms general (dependencias entre objetos).

    z Las vistas se pueden anidar: Vistas compuestas y simples.{ Generalizacin: Patrn Composite{ Generalizacin: Patrn Composite.

    z La relacin entre la vista y el controlador: patrn St t ( bj t t l it )Strategy (un objeto que representa un algoritmo).

    z Otros patrones:z Otros patrones:{ Factory Method: especifica la clase controlador predeterminada

    para una vista.{ Decorator: Aade capacidad de desplazamiento a una vista

    10

    { Decorator: Aade capacidad de desplazamiento a una vista.

  • El catlogo de patronesEl catlogo de patronesPropsito

    Creacin Estructurales De Comportamiento

    Clase Factory Method Adapter (de clases) Interpreter.Template MethodTemplate Method.

    m Objeto Abstract Factory Adapter (de objetos). Chain of Responsibility.mbito

    jBuilderPrototypeSingleton

    Bridge.Composite.Decorator.

    Command.Iterator.Mediator.

    Facade.Flyweight.Proxy.

    Memento.Observer.State.

    11

    Proxy. State.Strategy.Visitor.

  • El catlogo de patronesRelaciones entre

    los patrones.

    12

  • IndiceIndice

    z Introduccinz Introduccin.z Patrones de Creacin.{Singleton{Singleton.{Abstract Factory.{Factory Method.

    z Patrones Estructurales.z Patrones de Comportamiento.z Concl sionesz Conclusiones.z Bibliografa.

    131313

  • Patrones de CreacinPatrones de Creacin

    z Ab t l d i t i iz Abstraen el proceso de instanciacinz Ayudan a que el sistema sea independiente de

    cmo se crean componen y representan loscmo se crean, componen y representan los objetos.z Flexibilizan:Flexibilizan:{ qu se crea{ quin lo crea{ cmo se crea{ cundo se crea

    z Permiten configurar un sistema:z Permiten configurar un sistema:{ estticamente (compile-time){ dinmicamente (run-time)

    14

    ( )

  • SingletonSingleton

    z I t iz Intencin.{ 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 por ejemplo:sola instancia, por ejemplo:z Un gestor de ventanasz Una nica cola de impresinz Un nico sistema de ficherosUn nico sistema de ficherosz Un nico fichero de log, o un nico repositorio.

    {Cmo asegurarlo? una variable global hace el objeto accesible pero se puede instanciar varias vecesaccesible, pero se puede instanciar varias veces.

    {Responsabilidad de la clase misma: actuar sobre el mensaje de creacin de instancias

    15

  • SingletonSingleton

    z Aplicabilidad.{ Cuando debe haber una sola instancia, y debe ser accesible a los

    clientes desde un punto de acceso conocido.clientes desde un punto de acceso conocido.{ Cuando la nica instancia debe ser extensible mediante

    subclasificacin, y los clientes deben ser capaces de usar unainstancia extendida sin modificar su cdigoinstancia extendida sin modificar su cdigo.

    z Estructura.Singleton

    static Singleton uniqueInstancesingletonData

    static Singleton Instance ()SingletonOperation ()GetSingletonData ()

    return uniqueInstance

    16

  • SingletonSingletonz Participantes:p{ Singleton:

    z Define una operacin de clase, llamada Instance que deja a los clientesacceder 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 y la representacin. Se puedep y p p

    subclasificar 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.

  • SingletonSingletonz Implementacin:z Implementacin:

    class Singleton {private:p

    static Singleton* _instance;void otherOperations();

    protected: Singleton();

    public: static Singleton* getInstance();

    }};

    Singleton* Singleton::_instance = 0;

    Singleton* Singleton::getInstance() {if (_instance == 0 )

    instance = new Singleton;18

    _instance = new Singleton;return _instance;

    }

  • Ejemplo#include "stdafx.h"#include using namespace std; Ejemploclass Maze{

    int x, y;public:

    M (i i ) ( ) ( ) {}Maze(int x, int y) : x(x), y(y) {}};

    class MazeFactory {blipublic:

    static MazeFactory* Instance();// existing interface goes hereMaze * createMaze(int x, int y) { return new Maze(x, y); };

    t t dprotected:MazeFactory() {};

    private:static MazeFactory* _instance;

    }};

    MazeFactory* MazeFactory::_instance = 0;

    M F t * M F t I t () {MazeFactory* MazeFactory::Instance () {if (_instance == 0) _instance = new MazeFactory;return _instance;

    }

    19void main(){

    Maze * m = MazeFactory::Instance()->createMaze(10,10);}

  • Singletonz Implementacin:{ Creacin de una subclase de singleton.{ D t i i l t l i I t { Determinar qu singleton queremos usar en la operacin Instance.{ Registro de objetos singleton.

    class Singleton {public:

    static void Register(const char* name, Singleton*);static Singleton* Instance();static Singleton Instance();

    protected:static Singleton* Lookup(const char* name);

    private:static Singleton* _instance;static List* _registry;

    };Si l t * Si l t I t () {Singleton* Singleton::Instance () {

    if (_instance == 0) {const char* singletonName =getenv("SINGLETON");// user or environment supplies this at startup

    20

    // use o e o e supp es s a s a up_instance = Lookup(singletonName); // Lookup returns 0 if there's no such singleton

    }return _instance; }

  • SingletonSingleton

    z Dnde se registra la clase?{ Una posibilidad es en el constructor.

    MySingleton::MySingleton() {// ...Singleton::Register("MySingleton", this);

    {Entonces hay que instanciar la clase!

    g g ( y g )}

    {Se puede crear una instancia global:static MySingleton theSingleton;

    21

  • SingletongEjemplo

    MazeFactory* MazeFactory::Instance () {class MazeFactory {public:

    static MazeFactory* Instance();// existing interface goes here

    MazeFactory MazeFactory::Instance () {if (_instance == 0) {const char* mazeStyle = getenv("MAZESTYLE");if (strcmp(mazeStyle, "bombed") == 0)

    i t B b dM F tg g

    protected:MazeFactory();

    private:static MazeFactory* instance;

    _instance = new BombedMazeFactory;} else if (strcmp(mazeStyle, "enchanted") == 0)

    _instance = new EnchantedMazeFactory;// ... other possible subclassesstatic MazeFactory _instance;

    };

    MazeFactory* MazeFactory::_instance = 0;

    } else_instance = new MazeFactory;

    return _instance;}}

    22

  • Abstract FactoryAbstract Factory

    z P itz Propsito.{Proporciona una interfaz para crear familias de objetos

    relacionados o que dependen entre s, sin especificar suslclases concretas.

    z Tambin Conocido Como.{ Kit{ Kit.

    zMotivacin.{ Ej.: un framework para la construccin de interfaces de usuario

    f ( fque permita varios look and feel (ej.: Motif y PresentationManager).zUna clase abstracta WidgetFactory con la interfaz para crear

    cada tipo de widgetcada tipo de widget.zUna clase abstracta para cada tipo de widget. Subclases

    concretas que implementan cada widget concreto.zDe esta manera los clientes son independientes del look

    23

    zDe esta manera, los clientes son independientes del lookand feel concreto.

  • Abstract FactoryAbstract Factory

    z Motivacin.

    WidgetFactory

    CreateScrollBar()CreateWindow()

    Client

    Window

    Productos

    MotifWidgetFactory PMWindowFactoryMotifWindowPMWindow

    Familias

    MotifWidgetFactory

    CreateScrollBar()CreateWindow()

    PMWindowFactory

    CreateScrollBar()CreateWindow()

    ScrollBar

    MotifScrollBarPMScrollBar

    24

  • Abstract FactoryAbstract Factory

    z Aplicabilidad. Usar este patrn cuando:{un sistema que deba ser independiente de cmo se

    dcrean, componen y representan sus productos.{un sistema que deba ser configurado con una familia de

    productos entre variasproductos entre varias.{una familia de objetos producto relacionados que est

    diseada para ser usada conjuntamente y es necesariodiseada para ser usada conjuntamente, y es necesariohacer cumplir esta restriccin.{se quiere proporcionar una biblioteca de clasesq p p

    productos, y slo se quiere revelar sus interfaces, no suimplementacin.

    25

  • Abstract FactoryAbstract Factory

    zEstructura:

    AbstractFactory

    createProductA ()

    ClientProductos()

    createProductB () AbstractProductA

    Familias

    ConcreteFactory1

    createProductA ()createProductB ()

    ConcreteFactory2

    createProductA ()createProductB ()

    AbstractProductB

    ProductA1ProductA2

    createProductB () createProductB ()

    ProductB1ProductB2

    26

  • Abstract FactoryAbstract Factoryz Participantes:p{ AbstractFactory. Declara una interfaz para operaciones que

    crean objetos producto abstractos.{ ConcreteFactory. Implementa las operaciones para crear objetosy p p p j

    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 Ab t tP d tAbstractFactory y AbstractProduct.z Colaboraciones.{ Normalmente slo se crea una nica instancia de una clase

    ConcreteFactory en tiempo de ejecucin. Esta fbrica concretacrea objetos producto que tienen una determinadaimplementacin.

    { Ab t tF t d l l i d bj t d t27

    { AbstractFactory delega la creacin de objetos producto en susubclase ConcreteFactory.

  • Abstract Factory

    C i

    Abstract Factory

    zConsecuencias.{Asla las clases concretas. Ayuda a controlar

    las clases de objetos que crea una aplicacin.Asla a los clientes de las clases deimplementacinimplementacin.{Facilita el reemplazo de familias de productos.{P l i t i t d t ({Promueve la consistencia entre productos (que

    la aplicacin use objetos de una sola familia ala vez)la vez).{Es difcil aadir un nuevo producto.

    28

  • Abstract FactoryAbstract FactoryEjemplo

    Ejemplo: aplicacin para construir un coche a partirde unas partes (motor, chasis, ...)

    t d l t d l i (f ili ) todos los componentes de la misma marca (familia) hay mltiples marcas (Ford, Toyota, Opel, ...) es responsabilidad del cliente ensamblar las piezasp p

    Car

    ToyotaCarFordCar PorscheCarCarPart

    CarBodyCarEngine

    29ToyotaBodyFordBody PorscheBodyToyotaEngineFordEngine PorscheEngine

  • Abstract FactoryAbstract FactoryEjemplo (ii)

    Cmo lo haramos sin utilizar el patrn Abstract Factory? Cmo lo haramos sin utilizar el patrn Abstract Factory?En un mtodo del cliente:

    CrearCoche (string marca) {

    if (marca == ford)FordCar coche = new FordCar ()

    El cdigo del cliente decide qu clase de coche construir (bien)else if (marca == toyota)

    ToyotaCar coche = new ToyotaCar ()else ;

    coche construir (bien) y qu subpartesinstanciar (mal). Puede

    if (marca == ford)FordEngine motor = new FordEngine ()

    else if (marca == toyota)ToyotaEngine motor = new ToyotaEngine ()

    cometerse el error de ensamblar partes de distintas familiaselse ;

    coche.add (motor);...

    distintas familias.

    30return coche;}

  • Abstract FactoryAbstract FactoryEjemplo (iii)

    CarPartFactory

    makeCar ()makeBody ()

    Client

    CarBody

    Productosy ()

    makeEngine ()CarBody

    ToyotaBodyFordBodyFamilias

    ToyotaFactory

    makeCar ()

    FordFactory

    makeCar ()

    CarEngine

    makeCar ()makeBody ()makeEngine ()

    makeCar ()makeBody ()makeEngine () ToyotaEngineFordEngine

    Car

    31ToyotaCarFordCar

  • Abstract FactoryAbstract FactoryEjemplo (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 ());...

    t h32

    return coche;}

  • Abstract Factory

    familia contiene una instancia de una marca de coche

    Abstract FactoryEjemplo (v)

    familia contiene una instancia de una marca de coche. Cmo se instancia familia?

    class CrearCoche {CarPartFactory * familia;y ;

    Car hacerCoche () {Car coche=familia->makeCar();coche.addEngine (familia->makeEngine());

    //presenta por pantalla la seleccinclass CrearCocheGUI : public CFrameWnd {//.

    id O B tt Cli k d () { g ( g ());coche.addBody (familia->makeBody ());...return coche;

    }

    void OnButtonClicked () {string familiasel;CrearCoche assembler;Car coche;// }

    static CrearCoche using (CarPartFactory * f) {CrearCoche l;l.factory (f);

    //if (familiasel == ford)

    assembler=CrearCoche::using (new FordFactory())else if (familiasel == toyota)

    bl C C h i ( T t F t ()) y ( );return l;}

    void factory (CarPartFactory * f) {

    assembler=CrearCoche::using (new ToyotaFactory())else ;

    coche = assembler.hacerCoche();}

    33

    y ( y ) {familia=f;

    }}

    }}

  • Abstract FactoryAbstract FactoryOtro 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

  • Abstract FactoryAbstract FactoryOtro Ejemplo: Laberinto

    class MazeFactory {public:

    MazeFactory();i t l M * M k M () tvirtual Maze* MakeMaze() const

    { 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{ t D ( 1 2) }{ return new Door(r1, r2); }

    };

    35

  • Abstract FactoryAbstract FactoryOtro Ejemplo

    Maze* MazeGame::CreateMaze (MazeFactory& factory) {Maze* aMaze = factory.MakeMaze();Room* r1 = factory.MakeRoom(1);Room r1 factory.MakeRoom(1);Room* r2 = factory.MakeRoom(2);Door* aDoor = factory.MakeDoor(r1, r2);aMaze->AddRoom(r1);M AddR ( 2)aMaze->AddRoom(r2);

    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());2 >S tSid (S th f t M k W ll())r2->SetSide(South, factory.MakeWall());

    r2->SetSide(West, aDoor);return aMaze;

    }

    36

    }

  • Abstract FactoryAbstract FactoryOtro Ejemplo

    class EnchantedMazeFactory : public MazeFactory {public:

    EnchantedMazeFactory();virtual Room* MakeRoom(int n) constvirtual Room* MakeRoom(int n) const{ return new EnchantedRoom(n, CastSpell()); }virtual Door* MakeDoor(Room* r1, Room* r2) const

    { return new DoorNeedingSpell(r1, r2); { g p ( , );}

    protected:Spell* CastSpell() const;

    };};// Make it possible to have rooms with bombs

    Wall* BombedMazeFactory::MakeWall () const {MazeGame game;BombedMazeFactory factory;Wall BombedMazeFactory::MakeWall () const {

    return new BombedWall;}Room* BombedMazeFactory::MakeRoom(int n) const {

    t R WithAB b( )

    y y;game.CreateMaze(factory);

    37

    return new RoomWithABomb(n);}

  • Factory MethodFactory Method

    z P itz Propsito.{Define una interfaz para crear un objeto, pero deja que

    sean las subclases quienes decidan qu clase instanciar.q qPermite que una clase delegue en sus subclases lacreacin de objetos.

    z Tambin Conocido Como.z Tambin Conocido Como.{Virtual Constructor.

    zMotivacin.{Ej.: un framework que pueda presentar distintos tipos de

    documentos (similar a MFCs).zDos abstracciones clave: aplicacin y documento (ambasp y (

    clases abstractas). Hay que subclasificarlas.zLa clase aplicacin no sabe qu subclase documento

    instanciar.

    38

  • Factory MethodFactory Method

    zMotivacin.Se le llama factory method (mtodode fabricacin)

    Documento

    +Abrir()

    Aplicacion

    +CrearDocumento()

    docs1..*

    Documento * doc = CrearDocumento()d h b k(d )b ()+Cerrar()

    +Guardar()+Deshacer()

    CrearDocumento()+NuevoDocumento()+AbrirDocumento()

    docs.push_back(doc)doc->Abrir()

    MiDocumentoMiAplicacion

    C D t ()return new MiDocumento

    +CrearDocumento()

    39

  • Factory MethodFactory Method

    A li bilid d U dz Aplicabilidad. Usar este patrn cuando:{ 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{ 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 seauxiliares, y queremos localizar qu subclase concreta es en la que se delega.

    z Estructura.Creator

    P d t

    Creator

    +FactoryMethod()+AnOperation()

    //product = factoryMethod()//Product +AnOperation()

    C t P d t C t C t

    //

    40

    ConcreteProduct ConcreteCreator

    +FactoryMethod()return new ConcreteProduct

  • Factory Method

    z P ti i t

    Factory Method

    z Participantes.{ Product (Documento). Define la interfaz de los objetos que crea

    el factory method.y{ ConcreteProduct (MiDocumento). Implementa la interfaz del

    producto.{ Creator (Aplicacion) Declara el factory method Puede tambin{ Creator (Aplicacion). Declara el factory method. Puede tambin

    dar una implementacin por defecto del factory method, quedevuelve un objeto de una clase por defecto.

    { ConcreteCreator (MiAplicacion) Sobreescribe el factory{ ConcreteCreator (MiAplicacion). Sobreescribe el factorymethod 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 delConcreteProduct adecuado.

    41

  • Factory Method

    z Consecuencias

    Factory Method

    z Consecuencias.{Los mtodos de fabricacin eliminan la necesidad de

    ligar clases especficas de la aplicacin a nuestrog p pcdigo.

    {El cdigo slo trata con la interfaz Product puede{El cdigo slo trata con la interfaz Product, puedefuncionar con cualquier clase ConcreteProductdefinida por el usuario.

    {Proporciona enganches para las subclases. Crearobjetos con un mtodo de fabricacin es ms flexibleobjetos con un mtodo de fabricacin es ms flexibleque hacerlos directamente.

    {El f t th d h k th d l42

    {El factory method es un hook method para que lassubclases den una versin extendida del cdigo.

  • Factory MethodFactory Method

    zConsecuencias.Figure ManipulatorFigure Manipulator

    +DownClick()+Drag()

    +CreateManipulator() g()

    +UpClick()p ()

    LineManipulator

    +DownClick()+Drag()

    TextManipulator

    +DownClick()+Drag()

    LineFigure

    +CreateManipulator()

    TextFigure

    +CreateManipulator() +Drag()

    +UpClick()+Drag()+UpClick()

    +CreateManipulator() +CreateManipulator()

    43

  • Factory Method

    I l t i

    Factory Method

    z Implementacin.{Dos variantes principales:z Cuando la clase Creator es abstracta y no

    proporciona implementacin para el mtodo defabricacin que declarafabricacin que declara.zCuando la clase Creator es concreta y proporciona

    una implementacin predeterminada para el mtodode fabricacin.

    {Mtodos de fabricacin parametrizados:Q l f t th d i ti dzQue los factory methods creen varios tipos deproducto. El mtodo recibe un parmetro queidentifica el tipo de objeto a crear.

    44

    p j

  • Factory MethodFactory Method

    z Implementacin.class Creator {{public:

    Product* GetProduct();protected:

    virtual Product* CreateProduct(); // factory methodprivate:

    Product* _product;};

    Product* Creator::GetProduct () {if ( d t 0) {if (_product == 0) {

    _product = CreateProduct();}ret rn prod ct

    45

    return _product;}

  • Factory MethodFactory Method

    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 class StandardCreator: public Creator {

    // nueva clase que herede de creator.class MyProduct : public Product {public:

    MyProduct();class StandardCreator: public Creator {public:

    virtual TheProduct* CreateProduct(); };

    MyProduct();// ...

    };StandardCreator myCreator;

    template TheProduct* StandardCreator::CreateProduct () {

    46

    StandardCreator::CreateProduct () {return new TheProduct;

    }

  • Factory MethodFactory MethodEjemplo

    class MazeGame {public:

    Maze* CreateMaze();

    Maze* MazeGame::CreateMaze () {Maze* aMaze = MakeMaze();Room* r1 = MakeRoom(1);();

    // factory methods:virtual Maze* MakeMaze() const{ return new Maze; }virtual Room* MakeRoom(int n) const

    Room r1 MakeRoom(1);Room* r2 = MakeRoom(2);Door* theDoor = MakeDoor(r1, r2);aMaze->AddRoom(r1);M AddR ( 2)virtual Room* MakeRoom(int n) const

    { return new Room(n); }virtual Wall* MakeWall() const{ return new Wall; }

    aMaze->AddRoom(r2);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());2 >S tSid (S th M k W ll())r2->SetSide(South, MakeWall());

    r2->SetSide(West, theDoor);return aMaze;

    }

    47

    }

  • Factory MethodFactory MethodEjemplo

    class BombedMazeGame : public MazeGame {public:

    BombedMazeGame();virtual Wall* MakeWall() constvirtual Wall MakeWall() const{ return new BombedWall; }virtual Room* MakeRoom(int n) const{ return new RoomWithABomb(n); }

    };

    class EnchantedMazeGame : public MazeGame {blipublic:

    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 tS ll() t

    48

    Spell* CastSpell() const;};

  • IndiceIndice

    z I t d iz Introduccin.z Patrones de Creacin.

    P t E t t lzPatrones Estructurales.{Composite.Co pos te{Facade.{Pro{Proxy.{Adapter.

    z Patrones de Comportamiento.z Conclusiones.

    494949z Bibliografa.

  • Patrones EstructuralesPatrones Estructurales

    E t bl l bj tz Establecen cmo se componen clases y objetospara formar estructuras mayores queimplementan nueva funcionalidadimplementan nueva funcionalidad.z Los patrones de clase usan la herencia para

    componer interfaces o implementaciones (ej :componer interfaces o implementaciones (ej.:Adapter).z Los patrones de objeto describen maneras dez Los patrones de objeto, describen maneras de

    componer objetos para implementar nuevafuncionalidadfuncionalidad.{ Flexibilidad, ya que se puede cambiar la configuracin

    en tiempo de ejecucin.

    50

  • CompositeCompositez Propsito.{ componer objetos en estructuras arborescentes para

    representar jerarquas parte-conjunto.z M ti iz Motivacin.{Aplicaciones grficas. Manipulacin de grupos de figuras de

    manera uniformemanera uniforme.Grafico

    dibuja ()graficos*

    dibuja ()

    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)

  • CompositeCompositez Una instancia en tiempo de ejecucin:

    :Dibujo

    z Una instancia en tiempo de ejecucin:

    :Linea :Texto:Dibujo

    graficos graficos graficos

    :Linea :Texto:Dibujo

    graficosgraficos

    :Rectangulo :Texto

  • Compositez Aplicabilidad. Usar el patrn cuando:Composite

    { Se quieren representar jerarquas todo/parte de objetos.{ Se quiere que los clientes ignoren la diferencia entre composiciones de

    objetos y objetos individuales. Los clientes tratarn todos los objetos en j y j jla estructura compuesta de manera uniforme.

    z Estructura.Client Component

    + Operation()+ Add(Component)

    children*

    ( p )+ Remove(Component)+ GetChild(int)

    Composite

    + Operation() forall g in children:O ti ()

    Leaf

    + Operation()

    53

    p ()+ Add(Component)+ Remove(Component)+ GetChild(int)

    g.Operation()+ Operation()

  • CompositeCompositez Participantes.p{ Component (Grafico).z Declara la interfaz de los objetos de la composicin.z Implementa el comportamiento por defecto de la interfaz comn ap p 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 si es apropiadoen la estructura recursiva y la implementa, si es apropiado.{ Leaf (Linea, Rectangulo, ).z Representa objetos hoja en la composicin. Una hoja no tiene hijos.z Define el comportamiento de los objetos primitivos en la composicinz Define el comportamiento de los objetos primitivos en la composicin.

    { Composite (Dibujo)z Define el comportamiento de los objetos con hijos en la composicin.z Almacena componentes hijoz Almacena componentes hijo.z Implementa operaciones relacionadas con los hijos de la interfaz de

    Component.{ Client

    54

    { Client.z Manipula objetos en la composicin a travs de la interfaz de

    Component.

  • CompositeCompositez Colaboracionesz Colaboraciones.{ Los clientes usan el interfaz de la clase Component para

    interaccionar con los objetos de la estructura compuesta.{ Si l bj t h j t l ti i di t t{ Si el objeto es hoja, entonces la peticin se cursa directamente.{ Si el objeto es un Composite, entonces normalmente redirige las

    peticiones a sus objetos hijo, quiz realizando operacionesadicionales antes y/o despus de la redireccin.

    z Consecuencias. El patron composite:{ Define jerarquas de objetos primitivos y compuestos Cuando{ Define jerarquas de objetos primitivos y compuestos. Cuando

    un cdigo cliente espera un objeto simple, se puede reemplazarpor uno compuesto.

    { Simplifica el cliente Se pueden tratar objetos simples y{ Simplifica el cliente. Se pueden tratar objetos simples ycompuestos de manera uniforme.

    { Facilita aadir nuevos tipos de componente.55

    { Puede hacer el diseo demasiado general. Complicado restringirlos tipos de componente de un composite.

  • CompositeComposite

    z I l t i Al d i iz Implementacin. Algunas decisiones:{ Referencias explcitas a los padres. En la clase component.{ Compartir componentes. til para ahorrar memoria, pero la{ 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 Equilibrio{ Declaracin de las operaciones de gestin de 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 hojacliente puede tratar de hacer cosas sin sentido sobre objetos hoja.z Declararla en la clase compuesto da seguridad, pero perdemos

    transparencia: leafs y composites tienen interfaces distintas.{ A veces es necesario tener en cuenta un orden para los hijos{ A veces es necesario tener en cuenta un orden para los hijos.{ Quin debe borrar los componentes?{ Cul es la mejor estructura de datos para almacenar los

    ?56

    componentes?.

  • CompositeCompositeEjemplo

    class Equipment {class Equipment {public:

    virtual ~Equipment();const char* Name() { return _name; }i t l W tt P ()virtual Watt Power();

    virtual Currency NetPrice();virtual Currency DiscountPrice();virtual void Add(Equipment*);virtual void Add(Equipment );virtual void Remove(Equipment*);virtual Iterator* CreateIterator() {return 0;}

    protected:E i t( t h *)Equipment(const char*);

    private:const char* _name;

    };};

    57

  • Compositeclass FloppyDisk : public Equipment {public:

    Ejemplo

    pFloppyDisk(const char*);virtual ~FloppyDisk();virtual Watt Power();virtual Currency NetPrice();virtual Currency NetPrice();virtual Currency DiscountPrice();

    };

    class CompositeEquipment : public Equipment {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 void Remove(Equipment*);virtual Iterator* CreateIterator();

    protected:CompositeEquipment(const char*);

    58

    p q p ( )private:

    List _equipment;};

  • CompositeCompositeEjemplo

    Currency CompositeEquipment::NetPrice () {Iterator* i = CreateIterator();Currency total = 0;for (i->First(); !i->IsDone(); i->Next()) {for (i >First(); !i >IsDone(); i >Next()) {

    total += i->CurrentItem()->NetPrice();}delete i;return total;

    }

    class Chassis : public CompositeEquipment {class Chassis : public CompositeEquipment {public:

    Chassis(const char*);virtual ~Chassis();i t l W tt P ()virtual Watt Power();

    virtual Currency NetPrice();virtual Currency DiscountPrice();

    };

    59

    };

  • CompositeCompositeEjemplo

    using namespace std;

    void main(){

    Cabinet* cabinet = new Cabinet("PC Cabinet");Chassis* chassis = new Chassis("PC Chassis");Chassis* chassis = new Chassis( PC Chassis );cabinet->Add(chassis);Bus* bus = new Bus("MCA Bus");bus->Add(new Card("16Mbs Token Ring"));( ( g ))chassis->Add(bus);chassis->Add(new FloppyDisk("3.5in Floppy"));cout

  • FacadeFacadez Propsito.{ Proporciona una interfaz unificada para un conjunto de interfaces de unp p j

    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{ 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 generalesdel subsistema.

    61

  • FacadeFacade

    z Motivacin.

    62

  • FacadeFacadez Aplicabilidad. Usar el patrn cuando:{ Queramos proporcionar una interfaz simple a un subsistema complejo.

    Slo los clientes que necesitan ms personalizacin necesitarn ir msall de la fachada.

    { Haya muchas dependencias entre los clientes y las clases queimplementan una abstraccin. La fachada desacopla el subsistema desus clientes y otros subsistemas (mejora acoplamiento y portabilidad).sus clientes y otros subsistemas (mejora acoplamiento y portabilidad).

    { Queramos dividir en capas nuestros subsistemas. La fachada es elpunto de entrada a cada subsistema.

    z E t tz Estructura.

    63

  • FacadeFacade

    z Participantesz Participantes.{ Facade (Compiler).z Sabe qu clases del subsistema son las responsables ante una

    peticinpeticin.z Delega las peticiones de los clientes en los objetos apropiados del

    subsistema.{ Clases del Subsistema (Scanner Parser ProgramNodeBuilder{ Clases del Subsistema (Scanner, Parser, ProgramNodeBuilder,

    CodeGenerator).z Implementan la funcionalidad del subsistema.z Realizan las labores encomendadas por el objeto Facade.p jz No tienen referencias al objeto Facade.

    z Observaciones.{ Los clientes se comunican en el sistema enviando peticiones al{ 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

    directamente a los objetos del subsistema.

  • FacadeFacade

    z C iz Consecuencias.{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 y puede reducir el tiempo dez Elimina dependencias y puede reducir el tiempo de

    compilacin.{No impide que las aplicaciones usen las clases del

    subsistema en caso necesariosubsistema en caso necesario.z Implementacin. Factores a tener en cuenta:{Reduccin del acoplamiento cliente-subsistema. Clase{Reduccin del acoplamiento cliente subsistema. Clase

    facade abstracta, con clases concretas para las diferentesimplementaciones de un subsistema.

    {Clases del subsistema pblicas o privadas Uso de espacios65

    {Clases del subsistema pblicas o privadas. Uso de espaciosde nombres en C++.

  • FacadeFacadeEjemplo: Una fachada para un sistema de compilacin

    class Scanner {class Scanner {public:

    Scanner(istream&);virtual ~Scanner();i t l T k & S ()virtual Token& Scan();

    private:istream& _inputStream;

    };};

    class Parser {public:

    Parser();Parser();virtual ~Parser();virtual void Parse(Scanner&, ProgramNodeBuilder&);

    };}

    66

  • Facadeclass ProgramNodeBuilder {

    FacadeEjemplo: Una fachada para un sistema de compilacin

    g {public:

    ProgramNodeBuilder();virtual ProgramNode* NewVariable ( const char* variableName ) const;virtual ProgramNode* NewAssignment ( ProgramNode* variablevirtual ProgramNode* NewAssignment ( ProgramNode* variable,

    ProgramNode* expression) const;virtual ProgramNode* NewReturnStatement ( ProgramNode* value ) const;virtual ProgramNode* NewCondition ( ProgramNode* condition,g ( g

    ProgramNode* truePart, ProgramNode* falsePart ) const;

    // ...ProgramNode* GetRootNode();ProgramNode GetRootNode();

    private:ProgramNode* _node;

    };

    67

  • FacadeEj l U f h d i t d il iclass ProgramNode {public:

    // program node manipulation

    Ejemplo: Una fachada para un sistema de compilacin

    // program node manipulationvirtual void GetSourcePosition(int& line, int& index);// ...// child manipulationvirtual void Add(ProgramNode*);virtual void Remove(ProgramNode*);// ...virtual void Traverse(CodeGenerator&);virtual void Traverse(CodeGenerator&);

    protected:ProgramNode();

    };class CodeGenerator {public:

    virtual void Visit(StatementNode*);i t l id Vi it(E i N d *)virtual void Visit(ExpressionNode*);

    // ...protected:

    CodeGenerator(BytecodeStream&);

    68

    CodeGe e a o ( y ecodeS ea &);protected:

    BytecodeStream& _output;};

  • Facadevoid ExpressionNode::Traverse (CodeGenerator& cg) {

    Vi it(thi )

    FacadeEjemplo: Una fachada para un sistema de compilacin

    cg.Visit(this);ListIterator i(_children);for (i.First(); !i.IsDone(); i.Next()) {

    i.CurrentItem()->Traverse(cg);() ( g);}

    }class Compiler { // Clase Facade

    blipublic:Compiler();virtual void Compile(istream&, BytecodeStream&);

    };};

    void Compiler::Compile ( istream& input, BytecodeStream& output ) {Scanner scanner(input);P N d B ild b ildProgramNodeBuilder builder;Parser parser;parser.Parse(scanner, builder);RISCCodeGenerator generator(output);

    69

    g ( p );ProgramNode* parseTree = builder.GetRootNode();parseTree->Traverse(generator);

    }

  • ProxyProxyz Propsitoz Propsito.{Proporcionar un representante o substituto de otro objeto

    para controlar el acceso a este.z Tambin conocido como.{Surrogate (substituto).

    z M ti iz Motivacin.{Retrasar el coste de creacin e inicializacin de un objeto

    hasta que sea realmente necesario.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

  • ProxyProxy

    zMotivacin.

    71

  • ProxyProxy

    z Aplicabilidadz 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 P )ImageProxy).{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++):

    C t l d f izContar el nmero de referencias.zCargar un objeto persistente en memoria.z Bloquear el objeto cuando se accede a l (no modificacin

    concurrente)72

    concurrente).z

  • ProxyProxyz Estructura.Estructura.

    73

  • ProxyProxyz 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 y se las mandan al sujeto Proxy Remoto: codifican las peticiones, y se las mandan al 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 peticinrealizar la 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 RealSubjectmanera que el Proxy se puede usan en vez del RealSubject.{ RealSubject.z Define el objeto real que el proxy representa.

    z Colaboraciones74

    z Colaboraciones.{ El proxy redirige peticiones al sujeto real cuando sea necesario,

    dependiendo del tipo de proxy.

  • ProxyProxyz Consecuenciasz Consecuencias.{ Introduce un nivel de indireccin adicional, que tiene muchos

    posibles usos:z U t d lt l h h d bj t idz Un proxy remoto puede ocultar el hecho de que un objeto reside en

    otro espacio de direcciones.z Un proxy virtual puede realizar optimizaciones, como crear objetos

    bajo demandabajo demanda.z Tanto los proxies de proteccin, como las referencias inteligentes

    permiten realizar tareas de mantenimiento adicionales cuando se accede a un objetoaccede a un objeto.

    { Otra optimizacin: copy-on-write.z Copiar un objeto grande puede ser costoso.z Si la copia no se modifica no hay necesidad de incurrir en dichoz Si la copia no se modifica, no hay necesidad de incurrir en dicho

    gasto.z El sujeto mantiene una cuenta de referencias, slo cuando se hace

    una operacin que modifica el objeto se copia realmente (ej : clase75

    una operacin que modifica el objeto, se copia realmente (ej.: clase String del ejemplo de operadores C++).

  • Proxyclass Image;extern Image* LoadAnImageFile(const char*);Proxy

    z Implementacin

    // external functionclass ImagePtr {public:

    ImagePtr(const char* imageFile);z Implementacin.{ Se pueden explotar las

    siguientes caractersticas del l j

    ImagePtr(const char imageFile);virtual ~ImagePtr();virtual Image* operator->();virtual Image& operator*();

    los lenguajes:z Sobrecargar el operador de

    acceso a miembros -> enC++

    private:Image* LoadImage();

    private:Image* image;C++. Image _image;const char* _imageFile;

    };ImagePtr::ImagePtr (const char* theImageFile) {

    _imageFile = theImageFile;_image = 0;

    }Image* ImagePtr::LoadImage () {Image ImagePtr::LoadImage () {

    if (_image == 0) {_image = LoadAnImageFile(_imageFile);

    }

    76

    return _image;}

  • ProxyProxyImage* ImagePtr::operator-> () {Image ImagePtr::operator () {

    return LoadImage();}Image& ImagePtr::operator* () {

    t *L dI ()return *LoadImage();}

    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 se llama: entonces hay que definir dichar operacin en el proxy y redirigir la llamadallamada.

    z A veces no hace falta que el proxy conozca el tipo concreto del sujeto real (si es suficiente con la interfaz de la clase abstracta Subject).

    77

  • ProxyProxyEjemplo: Un Proxy Virtual

    class Graphic {public: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;

    protected:pGraphic();

    };

    class Image : public Graphic {public:

    Image(const char* file); // loads image from a filevirtual ~Image();virtual void Draw(const Point& at);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);

    78

    virtual void Save(ostream& to);private:// ...};

  • ProxyProxyEjemplo: Un Proxy Virtual

    class ImageProxy : public Graphic { // la clase proxyclass ImageProxy : public Graphic { // la clase proxypublic:

    ImageProxy(const char* imageFile);virtual ~ImageProxy();i t l id D ( t P i t& t)virtual void Draw(const Point& at);

    virtual void HandleMouse(Event& event);virtual const Point& GetExtent();virtual void Load(istream& from);virtual void Load(istream& from);virtual void Save(ostream& to);

    protected:Image* GetImage();

    i tprivate:Image* _image;Point _extent;char* fileName;c a _ e a e;

    };

    79

  • ProxyProxyEjemplo: Un Proxy Virtual

    ImageProxy::ImageProxy (const char* fileName) { const Point& ImageProxy::GetExtent () {if ( t t P i t Z ) {

    ImageProxy::ImageProxy (const char fileName) {_fileName = strdup(fileName);_extent = Point::Zero; // don't know extent yet_image = 0;

    }

    if (_extent == Point::Zero) {_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

    }

  • ProxyProxyEjemplo: Un Proxy Virtual

    class TextDocument {public:

    TextDocument();void Insert(Graphic*);void Insert(Graphic*);// ...

    };

    TextDocument* text = new TextDocument;// ...text->Insert(new ImageProxy("anImageFileName"));

    81

  • Ejercicio (Junio de 208)z S l li i d did i t t t iz Sea la aplicacin de pedidos vista en temas anteriores:

  • EjercicioEjercicio

    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 seaccede 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, yste recuerda si ya se ha introducidocorrectamente o no.

  • Solucin (1)#include "stdafx.h"#include #include using std::cout;using std::cout;using std::string;using std::cin;class Cuenta {{public:

    virtual int obtenerDisponible () = 0;};class CuentaReal : public Cuentaclass CuentaReal : public Cuenta{private:

    int disponible;public:public:

    CuentaReal (int d ) : disponible (d) {}int obtenerDisponible() {return disponible; }

    };class ProxyCuenta: public Cuentaclass ProxyCuenta: public Cuenta{private:

    CuentaReal * cuenta;string clave;string clave;bool correcta;bool intro;

    public:ProxyCuenta ( string psswd CuentaReal & c ) :ProxyCuenta ( string 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 > cl;if (cl == clave) {

    correcta = true;return cuenta->obtenerDisponible();

    }else {

    correcta = false;cout

  • AdapterAdapterz Propsito.{ Convierte el interfaz de una clase en otro que espera el cliente.q p{ El adapter permite trabajar juntas a clases que de otra forma no podran por

    tener interfaces incompatibles.z Tambin conocido como.Tambin conocido como.{ Wrapper (envoltorio).

    z Motivacin.{ A veces una clase de una biblioteca que ha sido diseada para reutilizarse{ A veces una clase de una biblioteca que ha sido diseada para reutilizarse,

    no puede hacerlo porque su interfaz no coincide con la interfaz especfica de dominio que requiere la aplicacin.

    { Ej : un editor de dibujo Objetos grficos con una clase base abstracta{ Ej.: un editor de dibujo. Objetos 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

    86

    Adaptador de clase: Heredando el interfaz de Shape y la implementacin de TextView.

    Adaptador de objeto: Componiendo un objeto TextView dentro de un TextShape, e implementando TextShape en trminos de la interfaz de TextView.

  • AdapterAdapter

    zMotivacin.{ Adaptador de objeto.p j

    87

  • AdapterAdapter

    zEstructura.{Adaptador de clase.p

    88

  • AdapterAdapter

    zEstructura.{Adaptador de objeto.p j

    89

  • IndiceIndicez Introduccin.z Patrones de Creacin.z Patrones Estructurales.zPatrones de ComportamientozPatrones de Comportamiento.{Iterator.{Observer.{Template Method.{State.{Strategy.gy{Command.{Chain of Responsibility

    909090

    {Chain of Responsibility.z Conclusiones.z Bibliografa.

  • Patrones de ComportamientoPatrones de Comportamiento

    zTratan sobre algoritmos y la asignacin de responsabilidades entre objetos.p jzDescriben no slo patrones de clases y

    objetos sino patrones de comunicacinobjetos, sino patrones de comunicacin entre ellos.zCaracterizan un flujo de control complejo,

    difcil de seguir en tiempo de ejecucin.difcil de seguir en tiempo de ejecucin.zPermiten que el diseador se concentre

    l i t t bj tslo en cmo interconectar objetos.

  • IteratorIterator

    z Propsitoz Propsito.{ Proporciona un medio de acceder a los elementos de un

    contenedor secuencialmente sin exponer su representacin internainterna.

    z Tambin Conocido Como.{ Cursor.

    z Motivacin.{ Un contenedor (p.ej.: una lista) debe proporcionar un medio de

    navegar sus datos secuencialmente sin exponer su g prepresentacin 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.92

    { Dar la responsabilidad de acceder y recorrer el objeto lista a un objeto Iterator.

  • IteratorIterator

    z Motivacin.List ListIterator

    1 *list

    + Count()+ Append(Element)+ Remove(Element) + First()

    + Next()

    - index1 *

    + Next()+ 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

    elementos de la lista secuencialmenteelementos de la lista secuencialmente.{ Separar el mecanismo de recorrido del objeto lista, nos permite

    definir iteradores que implementen distintas estrategias.

    93

  • IteratorIteratorz 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()

    A d(El t)

    Iterator+ First()+ Next()Cli t+ Append(Element)

    + Remove(Element)

    Next()+ IsDone()+ CurrentItem()

    Client

    1 *list

    ListSkipList ListIterator SkipListIterator1skiplist

    *

    { 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)

  • IteratorIteratorz Aplicabilidad. Usar el patrn :{ para acceder al contenido de un contenedor sin exponer su{ 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. Iterator

    Aggregate

    +CreateIterator ()

    Iterator

    +First ()+Next ()+IsDone ()

    Client

    IsDone ()+CurrentItem ()

    ConcreteAggregate

    +CreateIterator () ConcreteIterator

    95return new ConcreteIterator (this)

  • IteratorIterator

    z Participantesz 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

  • IteratorIterator

    z Consecuenciasz 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.z Implementacin.{Quin controla la iteracin?. z El cliente controla la iteracin: iterador externo.z El iterador controla la iteracin: iterador internoz El iterador controla la iteracin: iterador interno.

    {Quin define el algoritmo de recorrido?z El iterador.z El d l it d l l l t d d lz El agregado, y el iterador slo almacena el estado de la

    iteracin. A este tipo de iterador se le llama cursor.{Cmo de robusto es el iterador?z Iterador robusto: Las inserciones y borrados no interfieren en el

    97

    z Iterador robusto: Las inserciones y borrados no interfieren en el recorrido (y se hace sin copiar el agregado).

  • IteratorIterator

    z I l t iz Implementacin.{Operaciones adicionales del iterador. z Por ejemplo, iteradores ordenados podran tener una operacinz Por ejemplo, iteradores ordenados podran tener una operacin

    Previous. Otras como SkipTo.{Usar iteradores polimrficos en C++.z Los iteradores polimrficos han de crearse dinmicamente por unz Los iteradores polimrficos han de crearse dinmicamente por un

    mtodo de fabricacin.z El cliente adems es responsable de borrarlos (propenso a

    errores)errores).{ Iteradores para Composites.z Los iteradores externos pueden ser complicados de implementar

    t t ien estructuras recursivas.{NullIterators.z Es un iterador degenerado que ayuda a manejar condiciones

    98

    g q y jlmite.

  • Iterator

    1 Interfaces de la lista y el iterador

    IteratorEjemplo

    1. Interfaces de la lista y el iterador.template class List {public:public:

    List(long size = DEFAULT_LIST_CAPACITY);long Count() const;Item& Get(long index) const;// ...

    };

    template template class Iterator {public:

    virtual void First() = 0;virtual void Next() = 0;virtual bool IsDone() const = 0;virtual Item CurrentItem() const = 0;

    protected:

    99

    protected:Iterator();

    };

  • Iterator

    2 Implementaciones de las subclases del iterador

    IteratorEjemplo

    2. Implementaciones de las subclases del iterador.template class ListIterator : public Iterator {public:public:

    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:const List* list;const List _list;long _current;

    };

    template template 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

  • Iterator

    3 U d l i d

    IteratorEjemplo

    3. Uso del iterador.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

  • IteratorIteratorEjemplo4. Evitar ajustarse a una implementacin concreta de la lista.j p{ Supongamos que tenemos SkipList y SkipListIterator.{ Se puede introducir un AbstractList para estandarizar la interfaz de la lista

    (List y SkipList son subclases de AbstractList).( y p ){ Para permitir iteracin polimrfica, AbstractList define un factory method

    CreateIterator.

    template template class AbstractList {public:virtual Iterator* CreateIterator() const = 0; //

    template Iterator* List::CreateIterator () const {

    return new ListIterator(this);}// ...

    };}

    // we know only that we have an AbstractListyAbstractList* employees;// ...Iterator* iterator = employees->CreateIterator();P i tE l (*it t )

    102

    PrintEmployees(*iterator);delete iterator;

  • IteratorIteratorEjemplo5. Asegurarse de que los iteradores se borran.g q{ 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(Iterator* i): i(i) { }IteratorPtr(Iterator* i): _i(i) { }~IteratorPtr() { delete _i; }Iterator* operator->() { return _i; }Iterator& operator*() { return *_i; }

    AbstractList* employees;// ...I P E l *

    p () { _ }private:

    // disallow copy and assignment to avoid// multiple deletions of _i:IteratorPtr(const IteratorPtr&);

    IteratorPtr iterator(employees->CreateIterator());

    PrintEmployees(*iterator);IteratorPtr(const IteratorPtr&);IteratorPtr& operator=(const IteratorPtr&);

    private:Iterator* _i;

    103

    _};

  • Iterator

    6. Un iterador interno.

    IteratorEjemplo

    { El iterador controla la iteracin, y aplica una operacin a cada elemento.{ La operacin se puede configurar:

    z Pasando un puntero a una funcin o a un objeto funcinz Pasando un puntero a una funcin, o a un objeto funcin.z Mediante subclasificacin.

    template class ListTraverser {public:ListTraverser(List* aList):_iterator(aList) { };

    template bool ListTraverser::Traverse () {bool result = false;for ( iterator First(); ! iterator IsDone(); iterator Next()) {

    bool Traverse();protected:virtual bool ProcessItem(const Item&) = 0;

    private:

    for ( _iterator.First(); !_iterator.IsDone();_iterator.Next()) {result = ProcessItem(_iterator.CurrentItem());if (result == false) break;

    }return result;

    ListIterator _iterator;};

    return result;}

    104

  • Iterator

    6 U i d i

    IteratorEjemplo

    6. Un iterador interno{ Imprimir los n primeros empleados de una lista.class PrintNEmployees : public ListTraverser {class PrintNEmployees : public ListTraverser {public:

    PrintNEmployees(List* aList, int n) :ListTraverser(aList),p y ( )_total(n), _count(0) { }

    protected:bool ProcessItem(Employee* const&);

    private:private:int _total;int _count;

    };}

    bool PrintNEmployees::ProcessItem (Employee* const& e) {_count++;e >Print();

    105

    e->Print();return _count < _total;

    }

  • Iterator

    6 U it d i t

    IteratorEjemplo

    List* employees;

    6. Un iterador interno{ Imprimir los n primeros empleados de una lista.

    List Employee employees;// ...PrintNEmployees pa(employees, 10);pa.Traverse();

    { Comparacin con un iterador externo:ListIterator i(employees);int count = 0;int count = 0;for (i.First(); !i.IsDone(); i.Next()) {

    count++;i.CurrentItem()->Print();if (count >= 10) break;

    }

    106

  • Iterator

    6 U i d i

    IteratorEjemplo

    6. Un iterador interno{ Pueden encapsular distintos tipos de operaciones.

    template template 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

  • ObserverObserver

    z P itz Propsito.{Define una dependencia de uno-a-muchos entre objetos, de

    forma que cuando un objeto cambie de estado se notifique y q j q yactualicen automticamente todos los objetos que dependen de l.

    z Tambin conocido comoz Tambin conocido como.{Dependents, Publish-Subscribe

    z Motivacin.{Mantener consistencia entre objetos relacionados.{No queremos obtener dicha consistencia aumentando el

    acoplamiento entre clasesacoplamiento entre clases.{Ej.: separacin de la presentacin en GUI de los datos de

    aplicacin subyacente.

    108

  • ObserverObserver

    z Motivacin.40

    A

    C

    D

    10

    20

    30

    40

    A B C DX 60 20 15 5Y 40 25 15 20

    B 0A B C D

    Y 40 25 15 20Z 10 10 20 60

    ModeloA: 40%B: 25%C 15%

    109

    C: 15%D: 20%

  • ObserverObserverz 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 hay que cambiar.y q{ 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)que los objetos estn fuertemente acoplados).

    z Estructura.Subject Observerobservers

    1 *0 1+Attach (Observer)+Detach (Observer)+Notify ()

    +Update()forall o in observers

    o.Update()

    1..*0..1

    o.Update()

    ConcreteSubject

    ConcreteObserver- observerState

    subject0..1

    110+GetState ()+SetState ()

    - subjectState +Update ()subject

    return subjectState observerState=subject->GetState()

  • ObserverObserverz Participantes.{ S bj t{ Subject.z Conoce a sus observadores, que pueden ser un nmero arbitrario.z Proporciona un interfaz para aadir y quitar objetos Observer.

    { Ob{ Observer.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 suz Implementa el interfaz de actualizacin del Observer para mantener su

    estado consistente con el del sujeto.

    111

  • ObserverObserverz 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.

    :ConcreteSubject barDiagram:ConcreteObserver

    sectorDiagram:ConcreteObserver

    SetState()Notify()

    Update()

    GetState()GetState()

    Update()GetState()

    112

  • ObserverObserver

    z Consecuenciasz Consecuencias.{ Permite modificar los sujetos y observadores de manera

    independiente.{ S d tili l j t i b d{ Se pueden reutilizar los sujetos sin sus observadores y

    viceversa.{ Se pueden aadir observadores sin modificar el sujeto u otros

    observadoresobservadores.{ Acoplamiento abstracto entre sujeto y observador. El sujeto no

    conoce la clase concreta de ningn observador (el acoplamientoes mnimo)es mnimo).

    { Capacidad de comunicacin mediante difusin. La notificacindel sujeto se enva automticamente a todos los observadoressuscritos. Se pueden aadir y quitar observadores en cualquierp y q qmomento.

    { Actualizaciones inesperadas. Una operacin aparentementeinofensiva sobre el sujeto puede desencadenar una cascada de

    bi l b d113

    cambios en los observadores.

  • ObserverObserver

    z Implementacinz Implementacin.{ Correspondencia entre sujetos y observadores.z Que el sujeto guarde referencias a los observadores a los que debe

    notificarnotificar.{ 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 sepaz 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()).

    { Quin dispara la actualizacin?Q pz 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.

    z Los clientes llaman a Notify(): Ventaja: se puede optimizar llamando a notify slo despus de varios

    cambios. Inconveniente: los clientes tienen la responsabilidad aadida de llamar

    114

    Inconveniente: los clientes tienen la responsabilidad aadida de llamar a Notify().

  • ObserverObserver

    z Implementacin.{Referencias perdidas a sujetos borrados.z Una manera de evitarlo es notificar a los observadores

    cuando se borra un sujeto.{Asegurarse de que el estado del Sujeto sea consistente{Asegurarse de que el estado del Sujeto sea consistente

    consigo mismo antes de la notificacin:z Hay que tener cuidado con las operaciones heredadas.Hay que tener cuidado con las operaciones heredadas.

    void MySubject::Operation (int newValue) {BaseClassSubject::Operation(newValue);BaseClassSubject::Operation(newValue);// trigger notification_myInstVar += newValue;// update subclass state (too late!)

    }115

    }

  • ObserverObserver

    z Implementacinz 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().zDos extremos:

    Modelo Push: el sujeto enva informacin detalla del cambio quieran Modelo Push: el sujeto enva informacin detalla del cambio, quieran los observadores o no.

    Inconveniente: observadores menos reutilizables. Modelo Pull: el sujeto no enva nada, y los observadores piden

    d l d t ll l it tdespus los detalles explcitamente.Inconveniente: puede ser poco eficiente.

    {Especificar las modificaciones de inters explcitamente:zMejorar la eficiencia haciendo que los observadores registrenzMejorar la eficiencia haciendo que los observadores registren

    solo aquellos eventos que les interesen.z Los observadores se subscriben a aspectos del sujeto.

    116

  • ObserverObserverz Implementacin.

    { Encapsular la semntica de las operaciones complejas{ Encapsular la semntica de las operaciones 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 necesario para que los observadores reflejen los cambios en el j p q j

    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

    +Attach (Observer o)

    Observer

    +Update(Subject)

    subjects

    1..*0..*ChangeManagerchman

    1Subject-Observer mapping

    observers

    +Attach (Observer o)+Detach (Observer)+Notify ()

    +Update(Subject)+Register (Subject,Observer)+Unregister (Subject,Observer)+Notify ()

    chman->Notify()

    Marcar todos los observersa actualizar.Actualizar los observerschman >Notify()

    chman->Registar(this,o)SimpleChangeManager DAGChangeManager

    Actualizar los observers 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)

  • ObserverObserverEjemplo

    class Subject;

    class Subject {public:

    virtual ~Subject();class Subject;class Observer {public:

    virtual ~ Observer();

    j ()virtual void Attach(Observer*);virtual void Detach(Observer*);virtual void Notify();

    protected:()virtual void Update (Subject* theChangedSubject) = 0;

    // soporte de mltiples subjectsprotected:

    protected:Subject();

    private:List *_observers;protected:

    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()) {

    i CurrentItem() >Update(this);

    118

    i.CurrentItem()->Update(this);}

    }

  • ObserverObserverEjemplo

    class ClockTimer : public Subject { class DigitalClock: public Widget, publicclass ClockTimer : public Subject {// Concrete subjectpublic:

    ClockTimer();

    class DigitalClock: public Widget, public Observer {public:

    DigitalClock(ClockTimer*);i t l Di it lCl k()

    ()virtual int GetHour();virtual int GetMinute();virtual int GetSecond();void Tick();

    virtual ~DigitalClock();virtual void Update(Subject*);// overrides Observer operationvirtual void Draw();void Tick();

    };

    void ClockTimer::Tick () {

    virtual void Draw();// overrides Widget operation;// defines how to draw the digital clock

    private:Cl kTi * bj t// update internal time-keeping state

    // ...Notify();}

    ClockTimer* _subject;};

    DigitalClock::DigitalClock (ClockTimer* s) {bj t} _subject = s;

    _subject->Attach(this);}DigitalClock::~DigitalClock () {

    119

    DigitalClock:: DigitalClock () {_subject->Detach(this);

    }

  • ObserverObserverEjemplo

    void DigitalClock::Update (Subject* theChangedSubject) {if (theChangedSubject == _subject) Draw();

    }void DigitalClock::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 public Observer {class AnalogClock : public Widget, public Observer {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);

  • Observer

    z Sistemas de eventos en Java (observer listener)

    ObserverUsos Conocidos

    z Sistemas de eventos en Java (observer=listener){AWT/Swing{ Javabeans

    z MVC en el sistema de ventanas de Smalltalk{Model=Subject{View=Observer{View=Observer{Controller=Cualquier objeto que cambie el estado de Subject

    z MVC en entornos web (J2EE){Model=EJB{View=JSP{Controller=servlet{Controller servlet

    121

  • Template MethodTemplate Methodz 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{ Permite que las subclases cambien pasos de un algoritmo sin cambiar

    su estructura.z Motivacin.{ Ej.: MFCs, abrir un fichero.

    Document Applicationdocs1 *

    void Application::OpenDocument (const char* name) {if (!CanOpenDocument(name)) {

    // cannot handle this document

    +Abrir()+Cerrar()+Guardar()

    D R d()

    pp

    +AddDocument()+OpenDocument()+DoCreateDocument()+CanOpenDocument()

    1..* // cannot handle this documentreturn;

    }Document* doc = DoCreateDocument();if (doc) {+DoRead() +CanOpenDocument()

    +AboutToOpenDocument()

    MyDocument MyApplication

    if (doc) {_docs->AddDocument(doc);AboutToOpenDocument(doc);doc->Open();doc >DoRead();

    122

    y

    +DoCreateDocument()+CanOpenDocument()+AboutToOpenDocument()

    +DoRead()

    return MyDocument

    doc->DoRead();}

    }

  • Template Methodz Aplicabilidad.Template Method

    {Para implementar las partes de un algoritmo que no cambian, y dejar que las subclases implementen el comportamiento que puede variarque puede 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 E t tz Estructura. ClaseAbstracta

    +TemplateMethod()+PrimitiveOperation1() +PrimitiveOperation2()+

    PrimitiveOperation1()PrimitiveOperation2()

    123

    ConcreteClass+PrimitiveOperation1()+PrimitiveOperation2()

  • StateStatez Propsito.

    { Permitir que un objeto modifique su comportamiento cada vez que cambie su{ Permitir que un objeto modifique su comportamiento cada vez que cambie su estado interno.

    { Parecer que cambia la clase del objeto.z Tambin conocido como.

    { Objets for state (estados como objetos).z Motivacin.

    { TCPConnection para representar una conexin de red.p p{ 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

  • StateState

    zEstructura.

    125

  • StrategyStrategyz 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 Tambin conocido como.

    { Policy (poltica).z Motivacinz 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 estrategiaencapsulado se denomina estrategia.

    126

  • StrategyStrategy

    zEstructura.

    127

  • CommandCommandz Propsito.{ Encapsula peticiones a objetos{ Encapsula peticiones a objetos.{ Permite parametrizar a los clientes con diferentes peticiones, hacer

    cola o llevar un registro de peticiones, as como deshacer las peticionespeticiones.

    z Tambin conocido como.{ Action, Transaction.

    M ti iz Motivacin.{ Framework grfico tipo MFC. Peticiones de los distintos widgets

    encapsuladas como objetos.

    128

  • CommandCommand

    zM ti izMotivacin.

    129

  • CommandCommand

    z E t tz Estructura.

    130

  • Chain of ResposibilityChain of Resposibilityz 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{ 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 parte ms general.p p g

    131

  • Chain of ResposibilityChain of Resposibility

    zMotivacin.

    132

  • Chain of ResposibilityChain of Resposibility

    zEstructura.

    133

  • IndiceIndice

    z I t d iz Introduccin.z Patrones de Creacin.z Patrones Estructuralesz Patrones Estructurales.z Patrones de Comportamiento.zConclusioneszConclusiones.z Bibliografa.

    134134134

  • ConclusionesConclusiones

    zLos patrones de diseo capturan el conocimiento quezLos patrones de diseo capturan el conocimiento quetienen los expertos a la hora de disear.

    zLos patrones ayudan a generar software maleable(software que soporta y facilita el cambio, la reutilizaciny la mejora)y la mejora).

    zLos patrones de diseo son guas, no reglas rigurosas.

    zCada patrn describe la solucin a problemas que serepiten una y orta vez en nuestro entorno de forma querepiten una y orta vez en nuestro entorno, de forma quese puede usar esa solucin todas las veces que hagafalta.

    135

  • IndiceIndice

    z I t d iz Introduccin.z Patrones de Creacin.z Patrones Estructuralesz Patrones Estructurales.z Patrones de Comportamiento.z Conclusionesz Conclusiones.zBibliografa.

    136136136

  • BibliografaBibliografa

    D i tt l t f bl bj tz Design patterns, elements of reusable object-oriented software. Gamma, Helm, Jonhnson, Vlissides Addison Wesley 1995 (traducido alVlissides. Addison Wesley, 1995 (traducido al espaol en 2003).

    z Applying UML and Patterns. An introduction to Object Oriented Analysis and Design andObject-Oriented Analysis and Design and Iterative Development. 3rd Edition. Craig Larman Prentice Hall 2005Larman. Prentice Hall.2005.

    z http://hillside net/137137137

    z http://hillside.net/