Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostiladesignpatters PDF
Apostiladesignpatters PDF
Sumrio
Sumrio
Introduo aos Padres de Design ...................................... 1
1.1
1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7
1.2
1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7
1.3
1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7
1.4
1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7
1.5
1.5.1 1.5.2 1.5.3 1.5.4
PUC-Rio
Sumrio
1.5.5 1.5.6 1.5.7 Conseqncias...........................................................................................................33 Exemplo....................................................................................................................33 Cdigo do Exemplo ....................................................................................................33
1.6
1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7
O Padro Observer.................................................................................37
Objetivo ....................................................................................................................37 Contexto ...................................................................................................................37 Estrutura...................................................................................................................37 Aplicabilidade ............................................................................................................38 Conseqncias...........................................................................................................38 Exemplo....................................................................................................................38 Cdigo do Exemplo ....................................................................................................39
1.7
1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7
1.8
1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7
1.9
1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7
O Padro Proxy......................................................................................59
Objetivo ....................................................................................................................59 Contexto ...................................................................................................................59 Estrutura...................................................................................................................60 Aplicabilidade ............................................................................................................60 Conseqncias...........................................................................................................61 Exemplo....................................................................................................................61 Cdigo do Exemplo ....................................................................................................61
Bibliografia ........................................................................ 66
II
PUC-Rio
Lista de Figuras
Lista de Figuras
Figura 1.1 Framework para o Gerenciamento de Documentos..................................... 3 Figura 1.2 Estrutura do Padro Factory Method. .......................................................... 3 Figura 1.3 Exemplo do Padro Factory Method. .......................................................... 5 Figura 1.4 Estrutura do Padro Abstract Factory........................................................ 12 Figura 1.5 Exemplo do Padro Abstract Factory. ....................................................... 14 Figura 1.6 Estrutura do Padro Singleton.................................................................... 18 Figura 1.7 Exemplo do Padro Singleton. ................................................................... 20 Figura 1.8 xxxxxxx Facade......................................................................................... 23 Figura 1.9 Estrutura do Padro Facade. ...................................................................... 24 Figura 1.10 Exemplo do Padro Facade. .................................................................... 26 Figura 1.11 Estrutura do Padro Composite................................................................ 32 Figura 1.12 Exemplo do Padro Composite. ............................................................... 33 Figura 1.13 Estrutura do Padro Observer. ................................................................. 37 Figura 1.14 Adio de Um Novo Observador............................................................. 38 Figura 1.15 Notificao de Um Evento. ...................................................................... 38 Figura 1.16 Exemplo do Padro Observer. ................................................................. 39 Figura 1.17 Estrutura do Padro Strategy.................................................................... 43 Figura 1.18 Exemplo do Padro Strategy.................................................................... 45 Figura 1.19 Estrutura do Padro State. ........................................................................ 48 Figura 1.20 Mquina de Estados do Editor de Parmetros.......................................... 51 Figura 1.21 A Representao dos Estados Atravs de uma Hierarquia de Classes..... 52 Figura 1.22 Exemplo de Uso do Padro Proxy. .......................................................... 59 Figura 1.23 Estrutura do Padro Proxy. ...................................................................... 60
III
PUC-Rio
Captulo 1
Introduo aos Padres de Design
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PUC-Rio
1.1.2 Contexto
Considere o problema de construir um framework para aplicaes que gerenciem documentos. Tais aplicaes so tipicamente centradas nos documentos e nos arquivos que sero manipulados. A operao de uma aplicao dessa natureza comea, normalmente, com uma instruo para criar, ou editar, um documento de um processador de textos, uma planilha ou quaisquer outros documentos ou arquivos que possam ser manipulados. Um framework para este tipo de aplicao deve fornecer suporte de alto-nvel para as operaes usuais, tais como a criao, a abertura e a gravao de documentos. O suporte a estas operaes geralmente inclui um conjunto consistente de mtodos que so chamados em resposta aos comandos dos usurios. Para ilustrar esta discusso, iremos introduzir a classe Application como sendo a classe que fornece os mtodos necessrios para a manipulao de documentos. Um objeto da classe Application dever ser o ponto central para onde iro convergir todas as solicitaes originadas na interface com os usurios em resposta aos comandos por eles emitidos. Como no funo deste objeto implementar diretamente as solicitaes dos usurios, a classe Application ir delegar a maioria das mensagens para os objetos que efetivamente gerenciam os documentos. Por sua vez, a lgica para a implementao dos comandos de manipulao definida nestes objetos ir variar em funo do tipo do documento. Entretanto, existem operaes, tais como a exibio do ttulo do documento na barra de ttulo, que so comuns a todos os tipos de documentos. Isto sugere que o framework seja organizado de tal maneira que uma classe abstrata, chamada Document, contenha as propriedades comuns a todos os tipos de documentos, e que as subclasses de Document contenham as propriedades especficas aos diversos tipos de documentos suportados pela aplicao (Figura 1.1).
PUC-Rio
Introduo aos Padres de Design O que no foi dito at agora, e que tambm no mostrado no diagrama da Figura 1.1, como um objeto da classe Application ir criar as instncias das classes especficas aos diversos tipos de documentos existentes, de tal maneira que ela permanea independente do tipo de documento a ser manipulado. Este o objetivo do padro Factory Method.
1.1.3 Estrutura
A Figura 1.2 mostra um diagrama que ilustra os papis das classes e das interfaces que compem o padro Factory Method.
PUC-Rio
Introduo aos Padres de Design A seguir apresentado o papel de cada uma dos componentes do padro Factory
Method:
Product superclasse abstrata dos objetos que sero produzidos pelo Factory
Method.
ConcreteProductX classes concretas instanciadas pelo Factory Method. Se as classes no compartilharem uma lgica comum, a classe Product poder ser substituda por uma interface. CreationRequestor classe que precisa criar um objeto especfico. Ela o far atravs de uma instncia da classe Factory. FactoryIF os objetos que iro instanciar objetos da classe Product tero que implementar a interface FactoryIF. Factory classe que implementa a interface FactoryIF e, por conseguinte, define o mtodo que instancia uma das subclasses de Product (ConcreteProductX).
1.1.4 Aplicabilidade
Use o padro Factory Method quando: Uma classe no puder antecipar as classes dos objetos que ele precisa criar. Uma classe tiver que delegar as suas subclasses a responsabilidade pela criao de objetos de uma aplicao. Isso permitir localizar nas subclasses o conhecimento necessrio criao dos objetos.
1.1.5 Conseqncias
a. O
CreationRequestor
torna-se
da
classe
do
objeto classes
(ConcreteProductX)
instanciado,
com
quaisquer
concretas definidas pelo framework. b. O tipo dos produtos que sero manipulados pela aplicao pode ser mudado dinamicamente.
1.1.6 Exemplo
Suponha que estejamos desenvolvendo uma extenso da classe Socket com o objetivo de codificar streams de bytes enviados por uma conexo socket e de decodificar
PUC-Rio
PUC-Rio
/** * Constructor * @param key The key to use to perform the encryption. */ public Encryption(Key key) { this.key = key; } // Constructor(Key) /** * Return the key this object used for encryption and decryption. */ protected Key getKey() { return key; } // getKey() /** * This method returns an OutputStream that encrypts the bytes * written to it and writes the encrypted bytes to the given * OutputStream. * @param out The OutputStream that the OutputStream returned by * this method will write encrypted bytes to. */ abstract OutputStream encryptOutputStream(OutputStream out); /** * This method returns an InputStream that decrypts the stream of * bytes that it reads from the given InputStream. * @param in The InputStream that the InputStream returned by this * method will read bytes from. */ abstract InputStream decryptInputStream(InputStream in); } // class Encrypt ****************************************************************************** import import import import import java.io.InputStream; java.io.FilterInputStream; java.io.FilterOutputStream; java.io.OutputStream; java.security.Key;
/** * class to RSA encrypt/decrypt streams of bytes. */ public class RSAEncryption extends Encryption { /** * Constructor * @param key The key to use to perform the encryption. */ public RSAEncryption(Key key) { super(key); } // Constructor(Key) /** * This method returns an OutputStream that encrypts the bytes * written to it and writes the encrypted bytes to the given * OutputStream. * @param out The OutputStream that the OutputStream returned by * this method will write encrypted bytes to. */ OutputStream encryptOutputStream(OutputStream out) { return new RSAEncrytpedOutputStream(out); } // encryptOutputStream(OutputStream) /** * This method returns an InputStream that decrypts the stream of * bytes that it reads from the given InputStream.
PUC-Rio
/** * class to DES encrypt/decrypt streams of bytes. */ public class DESEncryption extends Encryption { /** * Constructor * @param key The key to use to perform the encryption. */ public DESEncryption(Key key) { super(key); } // Constructor(Key) /** * This method returns an OutputStream that encrypts the bytes * written to it and writes the encrypted bytes to the given * OutputStream. * @param out The OutputStream that the OutputStream returned by * this method will write encrypted bytes to. */ OutputStream encryptOutputStream(OutputStream out) { return new DESEncrytpedOutputStream(out); } // encryptOutputStream(OutputStream) /** * This method returns an InputStream that decrypts the stream of
PUC-Rio
PUC-Rio
/** * This class extends socket so that the stream of bytes that goes over * the net is encrypted. */ public class EncryptedSocket extends Socket { private static Encryption crypt; private Key key; /** * Constructor * @param key The key to use for encryption and decryption. This * object will determine the encryption technique to use * by calling the key object's getAlgorithm() method. * @param factory The Factory object to use to create Encryption * objects. * @exception NoSuchAlgorithmException if the key specifies an * encryption technique that is not available. */ public EncryptedSocket(Key key, EncryptionFactoryIF factory) throws NoSuchAlgorithmException { this.key = key; crypt = factory.createEncryption(key); } // Constructor(Key, EncryptionFactoryIF) /** * Returns an input stream for this socket that decrypts the inbound * stream of bytes. * * @return an input stream for reading decrypted bytes from this * socket. * @exception IOException if an I/O error occurs when creating the * input stream. */ public InputStream getInputStream() throws IOException { return crypt.decryptInputStream(super.getInputStream()); } // getInputStream() /** * Returns an output stream for this socket that encrypts the * outbound stream of bytes. * * @return an output stream for reading decrypted bytes from * this socket.
PUC-Rio
10
PUC-Rio
1.2.2 Contexto
Suponha que voc tenha que construir um framework para interfaces grficas (GUI) que possa ser utilizado sobre vrios sistemas gerenciadores de janelas diferentes, tais como MS Windows, Motif ou MacOS. Voc dever tambm fazer com que o framework funcione de acordo com as caractersticas visuais de cada uma das plataformas definidas. Uma possvel soluo para este problema ser definir uma classe abstrata para cada tipo de componente visual (text field, push button, list box e etc) e criar subclasses concretas que suportem tais componentes visuais em cada uma das plataformas em questo. Para tornar a implementao robusta, ser necessrio garantir que os objetos que implementam os componentes visuais sejam criados de acordo com a plataforma desejada. Neste contexto, uma fbrica abstrata ir declarar mtodos para a criao de instncias de cada uma das classes abstratas que representam componentes visuais. Enquanto isso, as subclasses concretas iro definir fbricas concretas que iro conter os mtodos necessrios criao dos componentes visuais de acordo com a plataforma escolhida.
1.2.3 Estrutura
A Figura 1.4 mostra um diagrama de classes que ilustra o papel que cada classe representa no padro Abstract Factory.
11
PUC-Rio
A seguir apresentado o papel de cada uma das classes do padro Abstract Factory: Client utiliza as classes que representam os componentes visuais para solicitar servios plataforma com a qual est trabalhando. A classe Client tem conhecimento apenas das classes abstratas que representam os componentes visuais abstratos. AbstractFactory declara os mtodos abstratos para a criao de instncias das classes concretas que implementam os componentes visuais. ConcreteFactoryX implementam os mtodos declarados na fbrica abstrata com o objetivo de criar instncias das classes concretas que implementam os componentes visuais na plataforma X. WidgetY classes abstratas que definem os componentes visuais que fazem parte do
framework.
PlatformXWidgetY classes concretas que implementam os componentes visuais Y na plataforma X.
12
PUC-Rio
1.2.4 Aplicabilidade
Use o padro Abstract Factory quando: Um sistema for independente de como os seus componentes so criados, compostos ou representados. Um sistema deve ser configurado como um produto de uma famlia de mltiplos produtos. Uma famlia de objetos-produto for projetada para ser usada em conjunto, e for necessrio garantir tal restrio. Quisermos fornecer uma biblioteca de classes de produtos e revelarmos apenas as interfaces, deixando as suas implementaes ocultas.
1.2.5 Conseqncias
c. As classes concretas que implementam os componentes visuais so independentes das classes que as usam, dado que a fbrica abstrata encapsula o processo de criao de tais componentes visuais. d. Inserir novas classes que dem suporte a novas plataformas uma tarefa simples. Uma classe que represente uma fbrica concreta usualmente referenciada em apenas um ponto do framework. De modo similar, bastante simples alterar uma fbrica concreta para tratar de uma nova plataforma a ser adicionada ao
framework.
e. Ao forarmos os clientes a usarem as fbricas concretas para a criao dos componentes visuais, o padro Abstract Factory assegura que os clientes usaro um conjunto de objetos consistentes com a plataforma com a qual desejam interagir. f. A principal deficincia do padro Abstract Factory o excesso de trabalho necessrio para criar um conjunto de classes que d suporte a uma nova plataforma.
1.2.6 Exemplo
Seja um programa que tenha por objetivo realizar diagnsticos remotos em computadores para um fabricante de equipamentos. Atravs dos anos, o fabricante em questo produziu computadores com substanciais diferenas nas suas respectivas
13
PUC-Rio
Introduo aos Padres de Design arquiteturas. Nos equipamentos mais antigos foram usados chips de CPU da Enginola, que so baseados na tradicional arquitetura CISC. Desde ento, o nosso fabricante produziu computadores baseados na sua prpria arquitetura RISC, chamdas de Ember, SuperEmber e UltraEmber. Os componentes principais destas vrias arquiteturas executam funes similares, porm possuem conjuntos de componentes distintos. A Figura 1.5 mostra um diagrama de classes que ilustra uma situao semelhante descrita acima, porm com apenas dois componentes para duas arquiteturas distintas.
14
PUC-Rio
/** * This method returns a concrete factory object that is an instance * of the concrete factory class that is appropriate for the given * computer architecture. * @param architecture a value indicating the architecture that a * concrete factory should be returned for. */ static final ArchitectureToolkit getFactory(int architecture) { switch (architecture) { case ENGINOLA: return enginolaToolkit; case EMBER: return emberToolkit; // ... } // switch String errMsg = Integer.toString(architecture); throw new IllegalArgumentException(errMsg); } // getFactory() /** * Method to create objects for remote testing CPUs. */ public abstract CPU createCPU() ; /** * Method to create objects for remote testing MMUs. */ public abstract MMU createMMU() ; //... } // ArchitectureToolkit
/** * This is an abstract class for objects that perform remote tests on MMUs. */ public abstract class MMU extends ComponentTester { //... } // class MMU
/** * Sample client class to show how a client class can create concrete * widget objects using an abstract factory */ public class Client { public void doIt () { ArchitectureToolkit af; af = ArchitectureToolkit.getFactory(ArchitectureToolkit.EMBER); CPU cpu = af.createCPU(); //... } //doIt } // class Client
/** * This is an abstract class for objects that perform remote tests on CPUs. */ public abstract class CPU extends ComponentTester { //... } // class CPU
15
PUC-Rio
/** * This is a class for objects that perform remote tests on Ember * architecture CPUs. */ class EmberCPU extends CPU { //... } // class EmberCPU
/** * This is a class for objects that perform remote tests on Ember * architecture MMUs. */ public class EmberMMU extends MMU { //... } // class EmbeMMU
/** * This is a concrete factory class for creating objects that are used to * perform remote tests on core components of ember architecture * computers. */ class EmberToolkit extends ArchitectureToolkit { /** * Method to create objects for remote testing ember CPUs. */ public CPU createCPU() { return new EmberCPU(); } // createCPU()
/** * Method to create objects for remote testing ember MMUs. */ public MMU createMMU() { return new EmberMMU(); } // createMMU() //... } // class EmberToolkit
/** * This is a class for objects that perform remote tests on Enginola * architecture CPUs. */ class EnginolaCPU extends CPU { //... } // class EnginolaCPU
/** * This is a class for objects that perform remote tests on Enginola * architecture MMUs. */ class EnginolaMMU extends MMU { //... } // class EnginolaMMU
/** * This is a concrete factory class for creating objects that are used to * perform remote tests on core components of enginola architecture * computers. */ class EnginolaToolkit extends ArchitectureToolkit {
16
PUC-Rio
/** * Method to create objects for remote testing enginola MMUs. */ public MMU createMMU() { return new EnginolaMMU(); } // createMMU() //... } // class EnginolaToolkit
17
PUC-Rio
1.3.2 Contexto
Algumas classes devem possuir exatamente uma instncia. Tais classes geralmente esto envolvidas no gerenciamento de algum recurso, ou controlando alguma atividade (controller). O recurso pode ser externo, como no caso em que um objeto gerencia a reutilizao de uma conexo com um gerenciador de banco de dados, ou o recurso pode ser interno, como no caso em que um objeto mantm estatsticas de erro para um compilador.
1.3.3 Estrutura
O padro Singleton relativamente simples, uma vez que ele envolve uma nica classe (Figura 1.6). A classe unitria possui uma varivel esttica que mantm uma referncia para a nica instncia que se deseja manipular. Esta instncia criada quando a classe carregada na memria ou quando ocorrer a primeira tentativa de acesso instncia. Devemos implementar a classe unitria de tal modo que no seja permitida a criao de instncias adicionais nica instncia permitida. Isto significa que devemos nos assegurar que todos os construtores da classe unitria sejam declarados como privados.
1.3.4 Aplicabilidade
Use o padro Singleton quando:
18
PUC-Rio
Introduo aos Padres de Design Deve haver apenas uma nica instncia de uma classe, e essa instncia deve poder ser acessada pelos clientes a partir de um ponto bem conhecido. Quando a nica instncia tiver que ser estendida atravs de subclasses, possibilitando aos clientes usar a instncia estendida sem alterar os seus respectivos cdigos.
1.3.5 Conseqncias
a. Como a classe Singleton encapsula a sua nica instncia, ela pode ter o controle total de como e quando os clientes acessam esta instncia. b. O padro Singleton representa uma melhoria em relao ao uso de variveis globais. c. A classe Singleton pode ser estendida atravs de subclasses, sendo bastante simples configurar uma aplicao para trabalhar com a extenso. d. A classe Singleton pode ser modificada para suportar um nmero maior de instncias, embora ainda se possa ter o controle do nmero de instncias que uma aplicao v utilizar. e. Uma outra maneira de implementar um Singleton atravs do uso de mtodos estticos; entretanto, a utilizao desta tcnica dificulta a mudana de um projeto para permitir um nmero maior de instncias. Alm disso, as funes estticas no so polimrficas, o que significa que as subclasses no podem redefini-las polimorficamente.
1.3.6 Exemplo
Suponha que desejemos escrever uma classe que possa ser usada por uma applet para garantir que no mais que um udio clip possa ser executado em um dado momento. Se uma applet contiver dois trechos de cdigo que reproduzam udio clips independentemente, ento seria possvel para ambas reproduzirem os udio clips ao mesmo tempo. Tal ocorrncia poderia levar uma condio de erro, ou a uma situao de grande confuso, com o usurio ouvindo um mix de sons no muito agradvel. Para evitar tal situao necessrio que a classe responsvel pela reproduo de udio clips interrompa a reproduo corrente antes de comear uma nova. Um meio de implementar essa poltica assegurar que exista uma nica instncia da classe de reproduo, e que ela seja compartilhada por todas as classes que desejem reproduzir
19
PUC-Rio
Introduo aos Padres de Design udio clips. Se todas as solicitaes para reproduo forem direcionadas para um nico objeto, ser fcil para este objeto parar a reproduo de um clip antes de iniciar a seguinte. A Figura 1.7 mostra um diagrama com uma classe com as caractersticas descritas acima.
20
PUC-Rio
import java.applet.AudioClip; /** * This class can be used to avoid playing two audio clips at the same * time. The class has only one instance that can be accessed through * its getInstance method. When you play audio clips through that * object, it stops the last audio clip it was playing before * it starts the newly requested one. If all audio clips are played * through the AudioClipManager object then there will never be more * than one audio clip playing at the same time. */ public class AudioClipManager implements AudioClip{ private static AudioClipManager myInstance = new AudioClipManager(); private AudioClip prevClip; // previously requested audio clip /** * This private constructor is defined so the compiler won't * generate a default public constructor. */ private AudioClipManager() { } /** * Return a reference to the only instance of this class. */ public static AudioClipManager getInstance() { return myInstance; } // getInstance() /** * Start playing this audio clip. Each time this method is called, * the clip is restarted from the beginning. */ public void play() { if (prevClip != null) prevClip.play(); } // play() /** * Stop the previously requested audio clip and play the given audio * clip. * @param clip the new audio clip to play. */ public void play(AudioClip clip) { if (prevClip != null) prevClip.stop(); prevClip = clip; clip.play(); } // play(AudioClip) /** * Starts playing this audio clip in a loop. */ public void loop() { if (prevClip != null) prevClip.loop(); } // loop()
21
PUC-Rio
22
PUC-Rio
1.4.2 Contexto
Estruturar um sistema em subsistemas ajuda a reduzir a complexidade. Um objetivo comum a todos os projetos minimizar a comunicao e as dependncias entre os subsistemas que compem uma aplicao. Uma maneira de alcanar este objetivo introduzir um objeto facade (fachada), o qual fornece uma interface nica para os recursos e facilidades mais gerais de um subsistema.
1.4.3 Estrutura
A Figura 1.9 mostra um diagrama de classes que ilustra a estrutura geral do padro
Facade.
O objeto Client interage com o objeto Facade, que fornece a funcionalidade necessria para a interao com o restante dos objetos. Se existir alguma funcionalidade adicional, necessria apenas para alguns clientes, ser melhor ento que o objeto
23
PUC-Rio
Facade fornea um mtodo para que seja possvel acessar diretamente o objeto
responsvel por tal funcionalidade, ao invs de inclu-la na interface do objeto Facade.
A seguir apresentado o papel dos componentes do padro Facade: Client precisa de uma funcionalidade de um dado subsistema mas no deseja estar a par da complexidade que envolve a execuo de tal funcionalidade. Facade conhece as classes do subsistema que so responsveis pelo atendimento de uma solicitao. Em funo disso, delega as solicitaes dos clientes aos objetos apropriados do subsistema. Classes do Subsistema implementam as funcionalidades do subsistema. Estas classes encarregam-se do trabalho que lhes foi atribudo pelo objeto Facade. Como regra geral, as classes do subsistema no devem manter referncias para o objeto
Facade.
1.4.4 Aplicabilidade
Use o padro Facade quando: Voc desejar fornecer uma interface simples para um subsistema complexo.
24
PUC-Rio
Introduo aos Padres de Design Existirem muitas dependncias entre os clientes e as classes que implementam uma certa abstrao. Ao introduzir uma fachada para reduzir o acoplamento entre o subsistema e os clientes (ou outros subsistemas), estar-se- promovendo a independncia e portabilidade dos subsistemas. Voc desejar estruturar em camadas seus subsistemas. Use uma fachada para definir o ponto de entrada para cada nvel de subsistema.
1.4.5 Conseqncias
a. Isola os clientes dos componentes de um subsistema, reduzindo o nmero de objetos com os quais os clientes tm que lidar, e tornando, assim, mais fcil o uso de tal subsistema. b. Promove o fraco acoplamento entre um subsistema e os seus clientes. Esta caracterstica permite variar os componentes de um subsistema sem afetar os seus clientes. c. Simplifica o porte de um sistema para outras plataformas, uma vez a sua utilizao diminui a ocorrncia de alteraes em cascata em funo da necessidade de uma alterao em um certo subsistema. d. No impede que as aplicaes utilizem diretamente as classes de um subsistema caso necessitem faz-lo. Assim, pode-se escolher entre a facilidade de uso e uma maior flexibilidade na manipulao das funcionalidades fornecidas por um subsistema.
1.4.6 Exemplo
Considere a organizao de um conjunto classes que fornece o servio de criao e envio de mensagens de e-mail (Figura 1.10). Como pode ser visto, trabalhar diretamente com este conjunto adiciona complexidade classe Client. Para interagir com estas classes, um cliente tem que conhecer pelo menos seis delas, os relacionamentos entre elas, e a ordem na qual os objetos so criados e trocam mensagens entre si. Se todo cliente tiver que lidar com toda essa complexidade adicional, ser difcil a reutilizao de tais classes em um outro contexto. O padro Facade fornece um meio de proteger um cliente da complexidade de usar este conjunto de classes. Isto feito atravs de um objeto adicional que oculta a maior parte das complexas interaes existentes. Como pode ser visto na Figura 1.10, os
25
PUC-Rio
Introduo aos Padres de Design clientes tm que estar a par apenas da existncia da classe MessageCreator. Isto possvel porque a lgica interna da classe MessageCreator responsvel pela criao das partes de uma mensagem de e-mail em uma determinada ordem.
/** * Constructor to create a MessageCreator object that will create an * e-mail message and send it to the given address. It will attempt to * infer the type of message to create from the "to" address. * @param to The address that this object will send a message to.
26
PUC-Rio
27
PUC-Rio
28
PUC-Rio
29
PUC-Rio
30
PUC-Rio
1.5.2 Contexto
Suponha que precisemos escrever um programa para a formatao de documentos. Ele dever formatar caracteres de linhas de texto, que so organizadas em colunas, que so organizadas em pginas. Alm disso, tal documento pode conter ainda outros elementos. Colunas e pginas podem conter frames, que por sua vez podem conter colunas. Colunas, frames e linhas de texto podem conter imagens. Como podemos ver, existe muita complexidade em uma aplicao dessa natureza. Objetos que representam pginas e frames tm que saber como manipular e combinar diversos tipos de componentes. O padro Composite procura remover tal complexidade fazendo com que estes objetos compostos precisem saber apenas como gerenciar um nico tipo de elemento. Isso alcanado fazendo com que todos os elementos de um documento composto tenham uma superclasse comum.
1.5.3 Estrutura
O relacionamento entre as classes que representam a estrutura do padro Composite pode ser visto na Figura 1.11.
31
PUC-Rio
A seguir apresentada a descrio das classes que participam da estrutura recursiva do padro Composite: AbstractComponent superclasse abstrata comum a todas a classes que definem os objetos que pertencem rvore de objetos que participam de um objeto composto. Os objetos compostos tratam normalmente os seus componentes como sendo instncias da classe AbstractComponent. ConcreteComponentX classes que definem os objetos que representam as folhas na rvore de componentes de um objeto composto. AbstractComposite superclasse abstrata comum a todos os objetos compostos que participam do padro Composite. Esta classe declara e fornece implementaes default para todos os mtodos usados no gerenciamento dos componentes de um objeto composto. ConcreteCompositeX as instncias destas classes so os objetos compostos que tm como componentes os objetos das outras subclasses de AbstractComponent.
1.5.4 Aplicabilidade
xxxxxxxxx: yyyy
32
PUC-Rio
1.5.5 Conseqncias
f. Zzzzzzzzzzzz.
1.5.6 Exemplo
O exemplo de aplicao do padro Composite uma verso mais detalhada do
/** * Instances of this class represent a page. */ class Page extends CompositeDocumentElement { //... } // class Page /** * Instances of this class represent a character in a document. */ class Character extends DocumentElement {
33
PUC-Rio
34
PUC-Rio
35
PUC-Rio
36
PUC-Rio
1.6.2 Contexto
1.6.3 Estrutura
37
PUC-Rio
1.6.4 Aplicabilidade
1.6.5 Conseqncias
g. Zzzzzzzzzzzz.
1.6.6 Exemplo
38
PUC-Rio
/** * Classes that implement this interface can register to receive * security notifications from SecurityNotifier objects. */ public interface SecurityObserver { public final int ALARM = 1; public final int LOW_POWER = 2; public final int DIAGNOSTIC = 3; /** * This is method is called to * this object. * @param device A number that * this notification. * @param event This should be * interface. */ public void notify(int device, } // interface SecurityObserver
deliver a security notification to identifies the device that originated one of the constants defined in this
int event);
/** * Instances of this class receive a notification from an object that is * can only deliver it to an object the implements the SecurityObserver * interface and apsses it on to a SecurityMonitor object that does not * implement SecurityObserver. */ class SecurityAdapter implements SecurityObserver { private SecurityMonitor sm; /** * Constructor */ SecurityAdapter(SecurityMonitor sm) { this.sm = sm;
39
PUC-Rio
40
PUC-Rio
41
PUC-Rio
1.7.2 Contexto
Existem muitos algoritmos para quebrar um stream de texto em linhas. Codificar de maneira fixa e rgida tais algoritmos nas classes que os utilizam no desejvel, por vrias razes: Os clientes que necessitam das quebras de linhas se tornam mais complexos se incluem o cdigo de quebra de linhas. Isso os torna maiores e mais difceis de manter, especialmente se suportam mltiplos algoritmos de quebra de linhas. Diferentes algoritmos sero apropriados em diferentes situaes. No seria uma boa estratgia suportar mltiplos algoritmos de quebra de linha se no for necessrio us-los. difcil adicionar novos algoritmos e variar os existentes quando a quebra de linha parte integrante de um cliente. Podemos evitar estes problemas definindo classes que encapsulam diferentes algoritmos de quebra de linhas. Um algoritmo encapsulado desta maneira chamado de strategy (estratgia).
1.7.3 Estrutura
A Figura 1.17 mostra um diagrama de classes com os principais componentes do padro Strategy.
42
PUC-Rio
A seguir apresentado um resumo do papel que cada classe exerce no padro em questo: Client uma classe Client delega a execuo de uma operao a uma classe abstrata ou a uma interface. Ela o faz sem conhecer a classe do objeto ao qual a operao delegada, e como tal classe implementa a operao solicitada. AbstractStrategy fornece uma interface comum para acessar as operaes definidas pelas suas subclasses. Pode-se usar uma interface, ao invs de uma classe abstrata, para exercer este papel. ConcreteStrateyX definem os diferentes mtodos que implementam as diferentes estratgias existentes para a operao solicitada pelo cliente.
1.7.4 Aplicabilidade
Use o padro Strategy quando: Muitas classes relacionadas diferem somente no seu comportamento. As estratgias fornecem uma maneira de configurar uma classe com um, dentre muitos comportamentos. Voc necessita de variantes de um algoritmo. Por exemplo, podemos definir algoritmos que reflitam diferentes solues de compromisso entre espao/tempo. Um algoritmo usa dados que os clientes deveriam desconhecer. Use o padro
43
PUC-Rio
Introduo aos Padres de Design Uma classe define muitos comportamentos, e estes aparecem em suas operaes como mltiplos comandos condicionais.
1.7.5 Conseqncias
a. Podemos usar este padro para criar diferentes hierarquias de estratgias, que iro definir famlias de algoritmos e comportamentos relacionados. b. Uma alternativa ao uso do padro Strategy seria especializar a classe Client para lhe dar diferentes comportamentos. Entretanto, isso congelaria o comportamento do cliente, misturando a implementao do algoritmo em questo com o resto do cdigo da classe Client, e tornando esta classe mais difcil de compreender, manter e estender. Alm disso, teramos a desvantagem de no poder variar os algoritmos dinamicamente. A soluo dada pelo padro Strategy permite variar o algoritmo independentemente dos seus clientes, tornando mais fcil troc-los, compreendlos e estend-los. c. Uma possvel desvantagem do padro Strategy estaria no fato de que um cliente pode ser obrigado, em algumas situaes, a conhecer a maneira pela qual as estratgias diferem uma das outras. Isso poderia levar a uma situao indesejvel, onde os clientes teriam que estar expostos aos detalhes de implementao das diferentes estratgias.
1.7.6 Exemplo
Suponha que precisemos escrever um programa para exibir calendrios. Um dos requisitos deste programa estar apto a exibir os feriados celebrados por diferentes naes e diferentes grupos religiosos. O usurio deste programa deve poder escolher quais grupos de feriados devem ser exibidos. Seria interessante atender este requisito colocando a lgica da aplicao relativa a cada grupo de feriados em uma classe separada, de tal maneira que tenhamos um pequeno conjunto de classes ao qual podemos facilmente adicionar novos elementos. Gostaramos tambm que as classes que fossem utilizar os servios para exibio dos calendrios no precisassem estar a par da existncia de nenhum feriado, ou conjunto de feriados, especfico. A Figura 1.18 mostra como utilizar o padro Strategy para implementar uma soluo para o problema descrito acima.
44
PUC-Rio
45
PUC-Rio
46
PUC-Rio
1.8.2 Contexto
Um objeto possui um conjunto de atributos, chamados conjuntamente de estado do objeto, cujos valores podem mudar de valor dinamicamente. Existem muitos algoritmos para quebrar um stream de texto em linhas. Codificar de maneira fixa e rgida tais algoritmos nas classes que os utilizam no desejvel, por vrias razes: Os clientes que necessitam das quebras de linhas se tornam mais complexos se incluem o cdigo de quebra de linhas. Isso os torna maiores e mais difceis de manter, especialmente se suportam mltiplos algoritmos de quebra de linhas. Diferentes algoritmos sero apropriados em diferentes situaes. No seria uma boa estratgia suportar mltiplos algoritmos de quebra de linha se no for necessrio us-los. difcil adicionar novos algoritmos e variar os existentes quando a quebra de linha parte integrante de um cliente. Podemos evitar estes problemas definindo classes que encapsulam diferentes algoritmos de quebra de linhas. Um algoritmo encapsulado desta maneira chamado de strategy (estratgia).
1.8.3 Estrutura
A Figura 1.19 mostra um diagrama de classes com os principais componentes do padro State.
47
PUC-Rio
A seguir apresentado um resumo do papel que cada classe exerce no padro em questo: Context classe cujas instncias exibem um comportamento que deve ser modelado por uma mquina de estados. As instncias desta classe determinam os seus respectivos estados correntes atravs de uma referncia (currentState) para uma instncia de uma subclasse concreta da classe ContextState. ContextState esta classe a superclasse de todas as classes usadas para representar os estados de uma instncia da classe Context. A classe ContextState define os seguintes mtodos: O mtodo start executa todas as tarefas necessrias para a inicializao da mquina de estados de um objeto, e retorna um objeto que corresponde ao estado inicial do objeto em questo. O mtodo processEvent um mtodo abstrato que recebe como argumento um evento e retorna o novo estado corrente do objeto em questo. Cada subclasse concreta de ContextState deve redefinir este mtodo de acordo com as necessidades do estado que ela representa. Quaisquer aes de sada (exit actions) relativas ao estado corrente devem ser executadas neste mtodo (desde que o evento tenha causado uma transio de sada do estado corrente).
48
PUC-Rio
Introduo aos Padres de Design O mtodo enter responsvel pela execuo das aes de entrada (entry
actions) de um estado. A implementao default, fornecida pela classe ContextState, no contm comandos (vazia), e deve ser redefinida pelas
subclasses que representam estados que contenham aes de entrada. Os mtodos operation1, operation2, ...., implementam as operaes especficas de cada um dos estados. ConcreteStateX subclasses concretas de ContextState, que representam os estados existentes em uma mquina de estados. Estas classes tm que implementar o mtodo
1.8.4 Aplicabilidade
Use o padro State quando: O comportamento de um objeto depender do seu estado e ele tiver que mudar de comportamento em tempo de execuo em funo de uma mudana no seu estado. As operaes contiverem grandes estruturas condicionais, com muitas alternativas. Freqentemente, tais estruturas iro conter grandes pores de cdigo que iro se repetir atravs de vrias operaes, gerando replicao desnecessria de cdigo. O padro State coloca cada ramo da estrutura condicional em uma classe separada, permitindo, assim, tratar os estados como se fossem objetos e tornar mais simples a implementao de uma mquina de estados.
1.8.5 Conseqncias
a. O padro State implementa uma mquina de estados particionando os comportamentos relativos aos estados e organizando tais comportamentos em objetos especficos. Desse modo, novos estados e transies podem ser facilmente adicionados mquina de estados atravs da definio de novas subclasses. b. Quando um objeto define o seu estado corrente unicamente em termos dos valores dos seus atributos, a suas transies de estado no tm representao explcita; elas ficam caracterizadas apenas pela mudana de valores de alguns atributos. A introduo de objetos distintos para representar os diferentes estados de mquina de estados torna as transies mais explcitas.
49
PUC-Rio
1.8.6 Exemplo
Suponha que estejamos escrevendo um editor de parmetros de programas. Uma caixa de dilogo para esta aplicao ter botes que iro representar as seguintes aes: Um boto de OK ir salvar os valores dos parmetros informados em um arquivo e na rea de trabalho do programa. Um boto de Save ir apenas salvar os valores dos parmetros informados em um arquivo. Um boto de Apply ir apenas salvar os valores dos parmetros informados na rea de trabalho do programa. Um boto de Revert ir restaurar os valores dos parmetros a partir do arquivo. possvel projetar este dilogo de modo que ele no tenha estados. Se um dilogo no contm estados, ele ir se comportar sempre da mesma maneira. O boto de OK estar sempre ativado, mesmo se o usurio tiver recm restaurado os valores dos parmetros a partir do arquivo. Se no houver outras consideraes, o uso de uma abordagem sem estados no design deste dilogo pode ser satisfatrio. Em alguns casos, entretanto, o comportamento descrito acima pode causar alguns problemas. A alterao dos valores dos parmetros na rea de trabalho do programa poder interromper o funcionamento do mesmo. O armazenamento dos valores em um arquivo pode tomar um tempo consideravelmente longo se ele estiver localizado em um servidor remoto. Um de evitar operaes desnecessrias inserir estados no dilogo de tal maneira que as operaes no possam ser executadas quando no forem necessrias. Ao invs disso, o dilogo s ir permitir a execuo destas operaes quando os valores dos parmetros forem diferentes dos valores armazenados no arquivo, ou dos valores existentes na rea de trabalho do programa. A Figura 1.20 mostra um diagrama de estados que representa o comportamento desejado.
50
PUC-Rio
Para implementar a mquina de estados da Figura 1.20, iremos criar cinco classes, como mostrado na Figura 1.21. Quatro delas iro corresponder a cada um dos quatro estados mostrado na mquina de estados da Figura 1.20, e a quinta ser a superclasse comum s quatro primeiras. A superclasse DirtyState possui um mtodo pblico chamado processEvent. Este mtodo recebe como parmetro um identificador de evento e retorna um objeto que representa o estado seguinte. Cada subclasse de DirtyState ir redefinir o mtodo
51
PUC-Rio
= = = =
1; 2; 3; 4;
= = = =
52
PUC-Rio
53
PUC-Rio
54
PUC-Rio
55
PUC-Rio
= = = =
1; 2; 3; 4;
= = = =
Button applyButton, saveButton, revertButton; private int state = NOT_DIRTY; /** * Constructor * @param parent The parent Frame */ Procedural(Frame parent) { super(parent, "Parameter Editor"); //... gotoState(NOT_DIRTY); } // Constructor() /** * respond to events based on the current state. * @param event An event code. * @exception IllegalArgumentException if event is an unexpected value. * @exception InternalError if the current state is corrupted. */ private void processDirtyStateEvent(int event) { switch (state) { case BOTH_DIRTY: switch (event) { case DIRTY_EVENT: // Do nothing break; case APPLY_EVENT: if (applyParam()) gotoState(FILE_DIRTY); break; case SAVE_EVENT: if (saveParam()) gotoState(PARAM_DIRTY); break; case REVERT_EVENT: if (revertParam()) gotoState(PARAM_DIRTY);
56
PUC-Rio
57
PUC-Rio
58
PUC-Rio
1.9.2 Contexto
Um objeto proxy um objeto que recebe chamadas de mtodos no lugar de um outro objeto. Os clientes enviam mensagens para um objeto proxy. Este, por sua vez, no fornece diretamente o servio solicitado. Ao invs disso, o objeto proxy aciona os mtodos do objeto responsvel por prover os servios solicitados pelos clientes. A Figura 1.22 mostra um diagrama de colaborao que ilustra o que foi dito.
Existem vrios tipos de servios que os objetos proxy esto habilitados a fornecer. Entre eles esto: A execuo de um servio muito demorado por ser respondida imediatamente pelo objeto proxy, enquanto o objeto alvo cuida da execuo da tarefa. Isso libera o cliente para executar outras tarefas, enquanto o servio solicitado executado pelo objeto alvo. Um proxy cria a iluso de que um objeto localizado em uma mquina remota esteja carregado no mesmo espao de endereamento do objeto cliente. Este tipo de
proxy conhecido como Proxy Remoto; sendo usado pelo Remote Method Invocation (RMI), presente na plataforma Java.
Um proxy pode controlar o acesso a um objeto provedor de servios. Este tipo de
59
PUC-Rio
Introduo aos Padres de Design Um proxy pode criar a iluso de que um objeto servidor exista antes mesmo da sua criao. Isso pode ser muito til quando o custo de criao do objeto servidor for muito alto e o uso dos seus servios no for muito freqente. Este tipo de proxy conhecido como Proxy Virtual.
1.9.3 Estrutura
A Figura 1.23 mostra um diagrama de classes com os principais componentes do padro Proxy.
O gerenciamento transparente de um objeto provedor de servios pode ser alcanado obrigando que todos os acessos a tal objeto seja feito atravs de um proxy. Para atingir a desejada transparncia, o objeto proxy e o objeto provedor de servios devem compartilhar a mesma superclasse ou implementar uma interface comum, como mostra a Figura 1.23. A Figura 1.23 no mostra nenhum detalhe de implementao de nenhum mtodo de gerenciamento em particular. Entretanto, o padro Proxy no ser muito til a no ser que seja empregado algum tipo de poltica de gerenciamento de acesso ao objeto provedor de servios.
1.9.4 Aplicabilidade
O padro Proxy aplicvel sempre que h necessidade de uma referncia mais verstil, ou sofisticada, do que um simples apontador para um objeto. Entre as situaes mais comuns nas quais o padro Proxy aplicvel podemos citar:
60
PUC-Rio
Introduo aos Padres de Design O uso de um proxy remoto para fornecer um representante local para um objeto que reside em outro espao de endereamento. O uso de um proxy de acesso quando for necessrio existir diferentes direitos de acesso a um objeto. O uso de um mecanismo de referncia mais sofisticado do que um simples ponteiro. Os casos tpicos incluem: A utilizao de um contador de referncias para um objeto real, de modo que o mesmo possa ser liberado quando no houver mais referncias para ele. Carregar um objeto persistente para a memria quando ele for referenciado pela primeira vez. Verificar se o objeto real est bloqueado antes de ser acessado, para assegurar que nenhum outro objeto possa alterar o seu contedo.
1.9.5 Conseqncias
a. Um proxy virtual pode executar otimizaes, tais como a criao de um objeto sob demanda. b. Tanto proxies de proteo como referncias sofisticadas permitem tarefas adicionais de organizao (housekeeping) quando um objeto acessado.
1.9.6 Exemplo
O padro Proxy no muito til na sua forma mais elementar. Ele deve ser combinado com um mecanismo de gerncia de acesso para que possamos obter algo de til. O exemplo a seguir usa o padro Proxy para postergar uma operao custosa at que ela seja realmente necessria. Se no for necessrio, a operao no ser nunca executada. O exemplo uma subclasse de java.util.Hashtable que funcionalmente equivalente a esta. A diferena est no modo como a subclasse em questo trata a operao de clonagem, que pode ser extremamente custosa.
61
PUC-Rio
62
PUC-Rio
63
PUC-Rio
64
PUC-Rio
65
PUC-Rio
Bibliografia
Bibliografia
[Gamma95] Gamma, E.; Helm, R.; Johnson, R. e Vlissides, J. Design Patterns:
Patterns Illustrated with UML. Vol. 1, John Wiley, New York, EUA,
1998.
66
PUC-Rio