padrões de projeto - deinf/ufmadeinf.ufma.br/~vidal/topicos2006_2/aula07.pdf · tópicos...

36
Tópicos Avançados em Linguagem de Programação Padrões de Projeto Prof. Alexandre Vidal DEINF-UFMA Fevereiro de 2007

Upload: trinhkhanh

Post on 28-Jan-2019

213 views

Category:

Documents


0 download

TRANSCRIPT

Tóp icos Avançados em L inguagem de P rogramação

Padrões de Projeto

Prof. Alexandre Vidal

DEINF-UFMA Fevereiro de 2007

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– intenção:

● converter a interface de uma classe em uma outra interface esperada por um cliente;

● o padrão Adapter pemite conectar duas classes que não se integrariam de outra forma.

– as known as● Wrapper

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– motivação:

● Algumas vezes, uma classe projetada para ser reusada não o é porque sua interface não combina com a interface requisitada por uma aplicação de um domínio específico;

● exemplo:– uma classe TextView existente poderia ser

reusada através de uma interface TextShape em um editor de desenhos para desenhar e organizar elementos gráficos (linhas, polígonos, etc.), tratando o texto como mais um tipo de elemento gráfico.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– aplicabilidade (quando usar o padrão):

● para usar uma classe existente, mas sua interface não combina com a interface que você precisa;

● para criar uma classe que combine com classes não previstas;

● como object adapter: muitas subclasses precisam ser reusadas, mas não é prático adaptá-las.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Estrutura Class Adapter

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Estrutura Object Adapter

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Participantes

● Target: – define a interface específica de um domínio usada pelo

cliente;● Client:

– colabora com objetos que se adaptam a interface Target;● Adaptee:

– define uma interface existente que precisa ser adaptada;● Adapter:

– adapta a interface de Adaptee a interface Target;

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Colaborações

● os clientes chamam operações sobre uma instância de Adapter;

● por sua vez, o adapter chama operações de Adaptee executam a requisição.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Conseqüências (Class Adapter)

✔ adapta Adaptee a Target através de uma classe Adapter concreta. Em conseqüência, não funciona quando se deseja adaptar uma classe e todas as suas subclasses;

✔ Adapter pode sobrescrever alguns dos comportamentos de Adaptee, uma vez que é uma subclasse de Adaptee;

✔ introduz apenas um objeto, e nenhum ponteiro adicional de indireção é necessário para acessar o adaptee.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Conseqüências (Object Adapter)

✔ um único Adapter funciona com muitos Adaptees— isto é, o próprio Adaptee e todas as suas subclasses (se existirem);

✔ o Adapter também pode adicionar funcionalidade a todos os adaptees a cada vez;

✔ é difícil sobrescrever o comportamento do Adaptee. Seria necessa io derivar ŕ Adaptee e fazer o Adapter referir-se a subclasse ao invés do proprio Adaptee.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– Implementação

● em C++ um Adapter deve herdar publicamente de uma classse Target e de modo privado de um Adaptee;

● Adapters plugáveis.

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural) (from GoF)class Shape {

public:

Shape();

virtual void BoundingBox(

Point& bottomLeft, Point& topRight

) const;

virtual Manipulator* CreateManipulator() const;

};

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural) (from GoF)class TextView {

public:

TextView();

void GetOrigin(Coord& x, Coord& y) const;

void GetExtent(Coord& width, Coord& height) const;

virtual bool IsEmpty() const;

};

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural) (from GoF)class TextShape : public Shape, private TextView {

public:

TextShape();

virtual void BoundingBox(

Point& bottomLeft, Point& topRight

) const;

virtual bool IsEmpty() const;

virtual Manipulator* CreateManipulator() const;

};

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural) (from GoF) void TextShape::BoundingBox ( Point& bottomLeft,

Point& topRight ) const

{

Coord bottom, left, width, height;

GetOrigin(bottom, left);

GetExtent(width, height);

bottomLeft = Point(bottom, left);

topRight = Point(bottom + height, left + width);

}

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural) (from GoF)bool TextShape::IsEmpty () const

{

return TextView::IsEmpty();

}

Manipulator* TextShape::CreateManipulator () const

{

return new TextManipulator(this);

}

Tóp icos Avançados em L inguagem de P rogramação

● Adapter (padrão estrutural)– usos conhecidos

● ver página xxx no GoF (traduzido);– Padrões Relacionados

● Bridge (estrutura similar ao Object Adapter, mas com diferentes intenções: promover independência entre interface e implementação);

● Decorator (promove um objeto sem mudar sua interface – mais transparente);

● Proxy (define um representante para um objeto – não muda sua interface).

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– intenção:

● desacopla uma abstração de sua implementação de modo que elas possam variar independentemente.

– a.k.a.: handle/body

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– motivação:

● o uso de herança para permitir diversas implementações de uma abstração pode não ser suficientemente flexível;

● interface e implementação ficam definitivamente ligadas e não podem ser usadas de modo independente.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– motivação:

● por exemplo: um código cliente deve ser capaz de criar um código de uma “janela”, sem se comprometer com um tipo específico de “janela” (e.g., Xwindow, IBM Presentation Manager, etc.);

● o padrão Bridge cria uma hierarquia para as interfaces de “janela” e uma hierarquia para cada implementação de “janela” específica de uma plataforma. A segunda hierarquia deriva de uma classe raiz WindowImp.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– aplicabilidade (quando usar o padrão):

● para evitar um conexão permanente entre abstração e implementação;

● para estender abstrações e suas implementações através de subclasses de modo independente;

● para evitar que mudanças na implementação atinjam os clientes;

● para evitar proliferação de classes (muitas classes de diferentes artefatos para diferentes ambientes em uma única hierarquia).

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Estrutura

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Participantes

● Abstraction: – define a interface da abstração;– mantém uma referência para o objeto Implementor;

● RefinedAbstraction: – estende a interface definida pela abstração;

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Participantes

● Implementor: – define a interface para as classes de implementação;– não precisa ser igual e normalmente é diferente da

interface da abstração;– enquanto a interface da implementação define apenas

operações primitivas, a interface da abstração define operações de alto nível baseadas nessas operações primitivas.

● ConcreteImplementor: – implementa a interface Implementor.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Colaborações

● abstrações encaminham requisições dos clientes aos objetos implementadores.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Conseqüências

✔ separa interface de implementação;✔ melhora as hierarquias de abstração e

implementação(evolução independente);✔ esconde detalhes de implementação dos clientes.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Implementação (aspectos)

● apenas um Implementor:– é um caso degenrado do Bridge;– não precisa criar uma classe Implementor abstrata;– ainda assim é útil por separar interface da

implementação;

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural)– Implementação (aspectos)

● quando, como e onde decidir qual classe Implementor deve ser instanciada ?

– no construtor da abstração, se ela conhece todas as implementações;

● possivelmente com base em parâmetros passados ao construtor;

– usar uma implementação default cambiável com o uso;– usar uma AbstractFactory.

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)class Window {public: Window(View* contents); // requests handled by window virtual void DrawContents(); virtual void Open(); virtual void Close(); virtual void Iconify(); virtual void Deiconify(); // requests forwarded to implementation virtual void SetOrigin(const Point& at); virtual void SetExtent(const Point& extent); virtual void Raise(); virtual void Lower(); virtual void DrawLine(const Point&, const Point&); virtual void DrawRect(const Point&, const Point&); virtual void DrawPolygon(const Point[], int n); virtual void DrawText(const char*, const Point&);protected: WindowImp* GetWindowImp(); View* GetView();private: WindowImp* _imp; View* _contents; // the window's contents};

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)– Window mantém uma referência para uma WindowImp, a

classe abstrata que declara uma interface para o sistema de janelas subjacente.

class WindowImp {public: virtual void ImpTop() = 0; virtual void ImpBottom() = 0; virtual void ImpSetExtent(const Point&) = 0; virtual void ImpSetOrigin(const Point&) = 0; virtual void DeviceRect(Coord, Coord, Coord, Coord) = 0; virtual void DeviceText(const char*, Coord, Coord) = 0; virtual void DeviceBitmap(const char*, Coord, Coord) = 0; // lots more functions for drawing on windows...protected: WindowImp();};

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)– Subclasses de Window definem os diferentes tipos

de janelas que a aplicação poderia usar, tais como janelas de aplicação, ícones, janelas transientes para diálogos, paletas flutuantes, etc.

class ApplicationWindow : public Window {public: // ... virtual void DrawContents();};void ApplicationWindow::DrawContents () { GetView()->DrawOn(this);}

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)– operações Window são definidas em termos da

interface WindowImp. Por exemplo, DrawRect extrai quatro coordenadas de seus parâmetros Point antes de chamar a operação WindowImp que desenha o retângulo na jnela:

void Window::DrawRect (const Point& p1, const Point& p2) { WindowImp* imp = GetWindowImp(); imp->DeviceRect(p1.X(), p1.Y(), p2.X(), p2.Y());}

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)● subclasses concretas de WindowImp “suportam” diferentes sistemas

de janela. A subclasse XwindowImp suporta o sistema X Window:

class XWindowImp : public WindowImp {

public:

XWindowImp();

virtual void DeviceRect(Coord, Coord, Coord, Coord);

// remainder of public interface...

private:

// lots of X window system-specific state, including:

Display* _dpy;

Drawable _winid; // window id

GC _gc; // window graphic context };

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)– essas subclasses implementam operações

WindowImp em termos de primitivas de sistema window.

void XWindowImp::DeviceRect ( Coord x0, Coord y0, Coord x1, Coord y1){ int x = round(min(x0, x1)); int y = round(min(y0, y1)); int w = round(abs(x0 - x1)); int h = round(abs(y0 - y1)); XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);}

Tóp icos Avançados em L inguagem de P rogramação

● Bridge (padrão estrutural) (from GoF)– Nesse exemplo Window tem a responsabilidade de

obter a instância correta de WindowImp;– WindowSystemFactory::Instance() retorna uma

AbstractFactory como um Singleton.WindowImp* Window::GetWindowImp () {

if (_imp == 0) {

_imp = WindowSystemFactory::Instance()->MakeWindowImp();

}

return _imp;

}

Tóp icos Avançados em L inguagem de P rogramação

● Proxy (padrão estrutural)– usos conhecidos

● ver página xxx no GoF (traduzido);– Padrões Relacionados

● Adapter;● Decorator;● Proxy.