Padrões de Projeto © 2001 Jaelson Castro Padrões de Projeto 1 Objetivos O que é entendido pelo termo padrão Que tipos de padrões têm sido identificados no desenvolvimento de software Como aplicar padrões de projeto durante o desenvolvimento de software Os benefícios e dificuldades que podem surgir quando usamos padrões © 2003 Jaelson Castro Padrões de Projeto 2 Padrões Projetar software OO bom e reusável é difícil. Mistura de específico+ genérico Impossível acertar da primeira vez Projetistas experientes usam soluções com as quais já trabalharam no passado. Padrões de projeto Sistematicamente © 2003 Jaelson Castro nomes, explicações, e avaliações Padrões de Projeto 3 Genesis Christopher Alexander, et. al. 1977 “Cada padrão descreve um problema que ocorre sempre em nosso ambiente, e então descreve o núcleo de uma solução para o problema, de que maneira você pode usar esta solução um milhão de vezes mais, sem fazê-la do mesmo jeito duas vezes.” Apropriada para prédios e pontes. Durante a última década, uma “comunidade de padrões” tem sido desenvolvida. © 2003 Jaelson Castro Padrões de Projeto 4 Genesis “Um padrão é a abstração de uma forma concreta que ocorre muitas vezes em contextos não arbitrários específicos.” Riehle and Zullighoven, 1996 “Cada padrão é uma regra de três partes, que expressa uma relação entre um certo contexto, um certo sistema de forças que ocorre repetidamente naquele contexto, e uma certa configuração de software que permite que estas forças resolvaos” Gabriel 1996. “Resolve um problema. É um conceito provado. A solução não é óbvia. Descreve um relacionamento. Os padrões têm um componente humano significativo.” Coplien 1996. © 2003 Jaelson Castro Padrões de Projeto 5 Características dos Padrões de Software Algo comprovado que captura, comunica os conhecimentos das melhores práticas. A solução não é óbvia. Descoberto, não inventado. O padrão tem um componente humano importante (ex. qualidades estéticas nos padrões de Alexander) © 2003 Jaelson Castro Padrões de Projeto 6 Anti-Padrões Anti-padrões é uma maneira de documentar soluções recorrentes de soluções que não tiveram sucesso © 2003 Jaelson Castro Pode também incluir soluções re-trabalhadas que sejam efetivas. Padrões de Projeto 7 Padrões Padrões de Análise: Padrões de Arquitetura: Descreve a estrutura e o relacionamento da maioria dos componentes de um sistema de software Padrões de Projeto: Descreve grupos de conceitos que representam construções comuns na modelagem do domínio. Estes padrões podem ser aplicáveis em um domínio ou em muitos. Identifica as relações internas entre um grupo de componentes de software e descreve suas responsabilidades, colaborações e relações estruturais. Idiomas Descreve como implementar aspectos específicos de um sistema de software numa dada linguagem de programação © 2003 Jaelson Castro Padrões de Projeto 8 Frameworks Sistemas de software parcialmente completos podem ter como alvo um tipo específico de aplicação Um sistema de aplicação apropriado para uma organização pode ser desenvolvido a partir de um framework para completar os elementos não concluídos e adicionar elementos específicos da aplicação © 2003 Jaelson Castro Padrões de Projeto 9 Diferenças entre os Padrões de Projeto e Frameworks Padrões são mais abstratos e genéricos que frameworks. Diferente de um framework, um padrão não é diretamente implementado num ambiente de software específico. Um framework pode ser escrito em linguagens de programação e não apenas estudado, mas executado e reusado diretamente. Ao contrário, padrões são implementados cada vez que são usados Padrões são mais primitivos que frameworks. Um framework típico contém vários padrões, mas o inverso nunca é verdade. © 2003 Jaelson Castro Padrões de Projeto 10 Catálogos e Linguagens de Padrões Um catálogo de padrões é um grupo de padrões que estão relacionados de uma certa forma e podem ser usados juntos ou independentemente. Os padrões numa linguagem de padrões estão mais relacionados, e trabalham juntos para solucionar problemas num domínio específico um conjunto de padrões que todos trabalham juntos para solucionar um grande problema. Ex: linguagem de padrões para integridade de informações (Cunningham95) © 2003 Jaelson Castro Padrões de Projeto 11 Princípios Presentes nos Padrões Abstração Encapsulamento Proteção de informação Modularização Separação de conteúdos Acoplamento e coesão Suficiência, completude e primitividade Separação entre política e implementação Único ponto de referência Dividir para conquistar © 2003 Jaelson Castro Padrões de Projeto 12 Padrões e requisitos nãofuncionais Padrões podem abordar as características descritas através de requisitos não funcionais: Modificabilidade Interoperabilidade Eficiência Confiabilidade Testabilidade Reusabilidade © 2003 Jaelson Castro Padrões de Projeto 13 Template para Documentação de um Padrão Elementos Mínimos: Nome do Padrão: Deve ser facilmente lembrado, reflete o conteúdo do padrão. Problema: Uma descrição do problema que pode ser escrito em forma de pergunta. Contexto: Descreve o contexto do problema. As circunstâncias ou pré-condições sob as quais o problema pode ocorrer. Forças: As restrições ou características que devem ser seguidas pela solução. As forças podem interagir e ter conflitos umas com as outras. Solução: Deve ser direta e precisa. © 2003 Jaelson Castro Padrões de Projeto 14 Template de padrão: Outros Elementos Um exemplo A razão que justifica a solução escolhida Padrão relacionado Uso conhecido do padrão Lista de outros nomes para o padrão Amostra de código do programa © 2003 Jaelson Castro Padrões de Projeto 15 Problemas com padrões de documentação Não há nada como um template perfeito. Considere © 2003 Jaelson Castro Porque ter um ‘Estilo da Empresa’? Quem usará os padrões documentados? Como eles serão usados? Qual a composição de texto, diagramas e código? Como prevenir erros de uso? Padrões de Projeto 16 Padrões de Projeto Padrões de Projeto foram introduzidos para a comunidade OO através de Gamma E., et al, Design Patterns, AddisonWesley, 1994 Eles categorizaram (23) padrões em três tipos: Criação (5) Estrutural (7) Comportamental (11) © 2003 Jaelson Castro Padrões de Projeto 17 Escopo Classe Relacionamentos entre classes e suas subclasses Não precisa executar nenhum código para determinar o uso dos padrões Estático, fixo em tempo de compilação Objeto © 2003 Jaelson Castro Confia em ponteiros de objetos. Pode ser alterado em tempo de execução, são mais dinâmicos. Padrões de Projeto 18 Propósito dos Padrões Criação Relacionado com o processo de criação do objeto Estrutural Relacionado com os relacionamentos entre classes e objetos Oferece caminhos efetivos para usar conceitos OO como herança, agregação e composição Comportamental Relacionado com os caminhos para que objetos e classes distribuam a responsabilidade para realizar a mesma tarefa. © 2003 Jaelson Castro Padrões de Projeto 19 Padrão criação Abstraem o processo de criação de instâncias (objetos), oferecendo flexibilidade no que é criado, por quem, como e quando. © 2003 Jaelson Castro Padrões de Projeto 20 Alguns Exemplos Padrão criação © 2003 Jaelson Castro Singleton Abstractfactory Builder FactoryMethod Prototype Padrões de Projeto 21 Padrão de Criação: Singleton Nome: Singleton (Único) Problema: Como pode ser construída uma classe que só pode ter uma única instância e que pode ser acessada globalmente dentro da aplicação? Contexto: Em algumas aplicações uma classe deve ter exatamente uma instância. © 2003 Jaelson Castro Padrões de Projeto 22 Padrão de Criação: Singleton Forças: Uma abordagem para tornar um objeto acessível globalmente é colocar a variável global, mas isto viola o encapsulamento. Outra abordagem é não criar uma instância de objeto em todo lugar, mas usar operações e atributos da classe (chamados `static´ em C++ e Java), mas isto limita a extensibilidade do modelo desde que a redefinição polimórfica das operações da classe não é possível em todos os ambientes de desenvolvimento (por exemplo C++) © 2003 Jaelson Castro Padrões de Projeto 23 Padrão de Criação: Singleton Solução: Criar uma classe com uma operação de escopo de classe (ou estática, ex: Java, C++) getInstance(), que: © 2003 Jaelson Castro Quando a classe é acessada pela primeira vez, a instância do objeto é criada e retornada para o cliente. Nos acessos subseqüentes de getInstance() nenhuma instância adicional é criada, mas a identidade do objeto existente é retornado. Padrões de Projeto 24 Padrão de Criação: Singleton Estrutura: Singleton static uniqueInstance singletonData getInstance() singletonOperation() getSingletonData() © 2003 Jaelson Castro return unique instance Padrões de Projeto 25 Padrão de Criação: Singleton Vantagens: © 2003 Jaelson Castro Oferece acesso controlado a única instância do objeto, pois a classe Singleton encapsula a instância. O espaço de nome não é necessariamente estendido com variáveis globais. A classe Singleton pode ter subclasses. Pode-se determinar que subclasses são instanciadas quando a classe Singleton é acessada pela primeira vez. Uma variação do padrão pode ser usada para criar um número específico de instâncias, se for requerido. Padrões de Projeto 26 Padrão Singleton – Exemplo Agate O sistema de gerenciamento de campanhas Agate precisa guardar informações a respeito da empresa. Estas informações só devem ser guardadas em um lugar dentro da aplicação, mas serão usadas por diferentes objetos. © 2003 Jaelson Castro Padrões de Projeto 27 Padrão Singleton – Exemplo Agate Quando um objeto cliente precisa acessar o objeto Company pode enviar a mensagem getCompanyInstance() e receber o identificador do objeto na resposta. O objeto cliente pode então enviar uma mensagem getCompanydetails() para o objeto Company © 2003 Jaelson Castro Padrões de Projeto 28 Padrão Singleton – Exemplo Agate Mas ela opera como uma empresa separada em cada país © 2003 Jaelson Castro diferentes detalhes registrados da empresa para cada país Padrões de Projeto 29 Padrão Singleton –Agate A classe Company só é instanciada uma vez. Ela é acessível globalmente. Diferentes subclasses de Company que são instanciadas quando necessário, dependendo das circunstâncias em tempo de execução. © 2003 Jaelson Castro Padrões de Projeto 30 Padrão AbstractFactory (kit) Meta Provê uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas. Motivação © 2003 Jaelson Castro Muitas vezes um programa necessita criar famílias inteiras de objetos que se relacionam entre si Padrões de Projeto 31 AbstractFactory Estrutura do Padrão client Window AbstractFactory createProductA() Widget Factory abstractProductA createProductB() productA2 productA1 ScrollBar ConcreteFactory1 createProductA() ConcreteFactory2 createProductA() createProductB() createProductB() MotifWidgetFactory PMWidgetFactory © 2003 Jaelson Castro abstractProductB productB2 productB1 Padrões de Projeto 32 AbstractFactory Participantes AbstractFactory ConcreteFactory Declara uma interface para um tipo de objeto (produto) ConcreteProduct Implementa a operações para criar objetos (produtos) concretos AbstractProduct Declara uma interface para operações que criam objetos (produtos) abstratos Define um objeto (produto) para ser criado pela ConcreteFactory correspondente Client © 2003 Jaelson Castro Usa apenas interfaces declaradas pela AbstractFactory e AbstractProduct Padrões de Projeto 33 AbstractFactory Aplicabilidade Use o Padrão AbstractFactory quando: © 2003 Jaelson Castro Um sistema deve ser independente de como seus produtos são criados, compostos e representados Um sistema deve ser configurado com uma entre múltiplas famílias de produtos Uma família de produtos foi projetada para trabalhar em conjunto e você necessita garantir o cumprimento destas restrições Você quer fornecer uma biblioteca de produtos (biblioteca ou framework), mas quer revelar apenas as interfaces dos produtos, mas não suas implementações Padrões de Projeto 34 AbstractFactory Colaborações Normalmente uma única instância de uma fábrica concreta é criada em run-time Esta fábrica concreta cria objetos (produtos) com uma implementação particular Para criar produtos diferentes, clientes devem usar fábricas concretas diferentes A AbstractFactory transfere a criação de objetos para as suas subclasses (ConcreteFactory) © 2003 Jaelson Castro Padrões de Projeto 35 AbstractFactory Conseqüências Isola Fábricas Concretas Facilita a Substituição de Famílias de Produtos Promove Consistência Entre Produtos Suporte a Novos Tipos de Produtos é difícil © 2003 Jaelson Castro Padrões de Projeto 36 Padrão Builder Intenção Separar construção da implementação de um objeto complexo, de modo que o mesmo processo de construção possa criar várias representações diferentes Motivação © 2003 Jaelson Castro Um programa muitas vezes necessita ler um formato de documento (fonte) e convertê-lo em vários outros formatos diferentes (objeto). Se os formatos (objeto) não são definidos a priori, é possível configurar o programa com um conversor (builder) que pode ser especializado em diferentes formatos e operações de conversão Padrões de Projeto 37 Padrão Builder Estrutura e Participantes builders builder Director construct() AbstractBuilder RTFReader for all objects in structure { builder.buildPart(); } buildPart() ASCIIConverter TeXConverter WordConverter ConcreteBuilder1 ConcreteBuilder2 ConcreteBuilde3r buildPart() getResult() buildPart() getResult() buildPart() getResult() Product1 © 2003 Jaelson Castro TextConverter ASCIIText Product2 TeXText Product3 WordText Padrões de Projeto 38 Padrão Builder Colaborações aClient aDirector aBuilder aBuilder = new ConcreteBuilder() aDirector = new Director(aBuilder) aDirector.construct() aBuilder.buildPartA() aBuilder.buildPartB() aBuilder.buildPartC() aBuilder.getResult() © 2003 Jaelson Castro Padrões de Projeto 39 Padrão Builder Aplicabilidade e Conseqüências Use o Padrão Builder quando O algoritmo para criar um objeto complexo deve ser independente das partes que constróem o objeto e de como elas são montadas O processo de construção necessita fornecer representações diferentes para o objeto que é construído Conseqüências do Padrão Builder © 2003 Jaelson Castro Permite variar a representação interna de um produto Isola os códigos de construção e representação Permite controle fino sobre o processo de construção Padrões de Projeto 40 Padrão FactoryMethod Intenção Definir uma interface para criação de um objeto, mas deixar que subclasses decidam as classes dos objetos a instanciar Motivação © 2003 Jaelson Castro Frameworks para criação de aplicações que trabalham sobre documentos necessitam ser refinados para definir exatamente qual a aplicação a ser criada, e qual o tipo de documento sobre a qual ela vai trabalhar Padrões de Projeto 41 Padrão FactoryMethod Estrutura e Participantes Application Document Creator Product factoryMethod() operation() ConcreteProduct ConcreteCreator factoryMethod() ... Product p = factoryMethod(); ... return new ConcreteProduct(); MyDocument MyApplication © 2003 Jaelson Castro Padrões de Projeto 42 Padrão FactoryMethod Aplicabilidade e Conseqüências Use o Padrão FactoryMethod quando: Uma classe não pode antecipar qual a classe do objeto que ela deve criar. Uma classe quer que suas subclasses definam o objeto que elas criam Classes delegam responsabilidades para uma entre muitas subclasses auxiliares, e você quer limitar o conhecimento de qual subclasse auxiliar recebeu a delegação. Conseqüências © 2003 Jaelson Castro Eliminam a necessidade de ligar classes específicas ao código Clientes necessitam criar subclasses sempre que precisam criar produtos Conectam hierarquias de classes paralelas Padrões de Projeto 43 Padrão Prototype Intenção Especificar os tipos de objetos a criar usando uma instância prototípica, e criar novos objetos através da clonagem deste protótipo Motivação © 2003 Jaelson Castro Você deseja parametrizar o funcionamento de uma parte da aplicação mas não quer usar herança, pois a quantidade de subclasses diferentes seria muito grande Padrões de Projeto 44 Padrão Prototype Participantes e Colaboradores Gráfico FerramentaGráfica Cliente prototype Prototype clone() operation() ... p = prototype.clone(); ... ConcretePrototype1 ConcretePrototype2 clone() clone() Pauta © 2003 Jaelson Castro Breve Padrões de Projeto 45 Padrão Prototype Aplicabilidade Use o Padrão Prototype Quando: Um sistema deve ser independente de como seus produtos são criados, compostos e representados, e © 2003 Jaelson Castro Quando as classes a instanciar são especificadas em runtime, por exemplo, através de carga dinâmica, ou; Quando instâncias de uma classe podem ter apenas poucas combinações de estados. Fica então mais conveniente clonar objetos em vez de construir novos objetos Padrões de Projeto 46 Padrão Prototype Conseqüências Reduz o número de classes que os clientes conhecem Permitem Que o cliente trabalhe com classes específicas de uma aplicação, sem necessidade de recompilação Adicionar e remover produtos em run-time Especificar novos objetos através da variação de valores Especificar novos objetos através de variação na estrutura Reduzir o número de subclasses Configuração dinâmica de aplicações Cada subclasse deve implementar o método clone() © 2003 Jaelson Castro Padrões de Projeto 47 Padrão Estrutural Tratam de compor classes e objetos para formar estruturas grandes e complexas © 2003 Jaelson Castro Padrões de Projeto 48 Padrão Estrutural:Exemplo Composite Adapter Bridge Decorator Facade Flyweight Proxy © 2003 Jaelson Castro Padrões de Projeto 49 Padrão Estrutural: Composite Nome: Composto Problema: Existe um requisito para representar hierarquias todo-parte, então ambos objetos (todo e parte) oferecem a mesma interface para objetos do cliente. Contexto: Numa aplicação tanto o objeto que contém quanto o que é componente são requeridos para oferecer o mesmo comportamento. © 2003 Jaelson Castro Objetos cliente devem ser capazes de tratar objetos compostos ou componentes do mesmo jeito (ex.: graphical drawing package) Padrões de Projeto 50 Padrão Estrutural: Composite Forças: O requisito que os objetos, tanto composto como componente, ofereçam a mesma interface, sugere que eles pertençam a mesma hierarquia de herança. © 2003 Jaelson Castro Isto permite que operações sejam herdadas e redefinidas com a mesma assinatura (polimorfismo). A necessidade de representar hierarquias todoparte indica a necessidade para uma estrutura de agregação Padrões de Projeto 51 Padrão Estrutural: Composite Solução : Combinar hierarquias de herança e agregação. © 2003 Jaelson Castro Padrões de Projeto 52 Padrão Estrutural: Composite Solução: Ambas subclasses, Leaf e Composite, têm uma operação redefinida usando o polimorfismo anOperation(). Na classe Composite esta operação redefinida invoca a operação relevante a partir de seus componentes usando um loop. A subclasse Composite também tem operações adicionais para gerenciar a hierarquia de agregação, então os componentes podem ser adicionados ou removidos. © 2003 Jaelson Castro Padrões de Projeto 53 Padrão Composite : Graphical drawing package G c i h p a r C t n e i l w a r d C t e g d l i h m e r G e v o c i h p a r G d a c i h p a r 0..* C m o t i s o p G e c i h p a r C e l c r i R e l g n a t c e n i L w a r d d w a r w a r d w a r d C t e g d l i h m e r G e v o c i h p a r G d a c i h p a r © 2003 Jaelson Castro Padrões de Projeto 54 Padrão Composite : Agate © 2003 Jaelson Castro Padrões de Projeto 55 Padrão Adapter Intenção Converter a interface de uma classe em outra interface que clientes possam utilizar. Compatibiliza classes, permitindo que trabalhem em conjunto. Motivação © 2003 Jaelson Castro Algumas vezes uma classe (de um toolkit) não é reusável somente porque sua interface não é compatível com a interface de uma aplicação de um domínio específico. A solução é criar um objeto adaptador, que encapsule e filtre as especificidades da classe adaptada, fornecendo uma interface que a aplicação espera utilizar Padrões de Projeto 56 Padrão (Class)Adapter Estrutura e Participantes Usando Herança Múltipla Client Target Adaptee request() specificRequest() Adapter request() © 2003 Jaelson Castro specificRequest() Padrões de Projeto 57 Padrão (Object)Adapter Estrutura e Participantes Usando Composição Client TextView Shape Target Adaptee request() specificRequest() DrawingEditor Adapter request() adaptee adaptee.specificRequest(); TextShape © 2003 Jaelson Castro Padrões de Projeto 58 Padrão Adapter Aplicabilidade Use o Padrão Adapter quando: © 2003 Jaelson Castro Você quer usar uma classe existente, e sua interface não é compatível com uma que você criou Você quer criar uma classe reusável que coopera com classes não relacionadas ou não previstas a priori, isto é, classes que não apresentam necessariamente a mesma interface (Somente para ObjectAdapter) Você precisa usar várias subclasses existentes (de Adaptee), mas é impraticável adaptar as interfaces de cada uma através de herança. Um ObjectAdapter pode resolver isto adaptando abstratamente a interface da superclasse. Padrões de Projeto 59 Padrão Adapter Conseqüências ClassAdapter Adapta uma classe concreta, mas NÃO SUAS SUBCLASSES Pode sobrepor alguns comportamentos do adaptado, visto que é uma subclasse da classe adaptada ObjectAdapter © 2003 Jaelson Castro Permite que um único Adapter trabalhe com muitos adaptados. Ou seja, o próprio Adaptee e suas subclasses. Pode adicionar funcionalidade extra a todos os adaptados de uma só vez. Padrões de Projeto 60 Padrão Bridge Intenção Desacoplar uma abstração de sua implementação, de modo que as duas possam variar independentemente. Motivação © 2003 Jaelson Castro Quando uma abstração pode ter várias implementações a solução usual é acomodar todas as implementações através de herança No entanto, herança liga de forma permanente uma abstração a uma implementação O padrão Bridge permite colocar as abstrações e suas implementações em diferentes hierarquias de classes, e permite que variem de forma independente Padrões de Projeto 61 Padrão Bridge Estrutura e Colaboradores Client WindowImp Window imp Abstraction Implementor operation() operationImp() imp.operationImpl(); RefinedAbstraction IconWindow © 2003 Jaelson Castro ConcreteImplementorA ConcreteImplementorB operationImp() operationImp() XWindowImp PMWindowImp Padrões de Projeto 62 Padrão Bridge Aplicabilidade Use o Padrão Bridge Quando: © 2003 Jaelson Castro Você quer evitar ligação permanente entre uma abstração e sua implementação. Pode ser, por exemplo, quando se deseja variar a implementação em run-time Tanto a abstração quanto a implementação devem ser extensíveis através de herança Mudanças na implementação de uma abstração não devem ter impacto sobre o cliente Padrões de Projeto 63 Padrão Bridge Conseqüências Desacoplamento entre interface e implementação Extensibilidade incrementada Implementação de uma abstração configurada em run-time Eliminação de dependências de compilação Criação de camadas de abstração que podem melhor estruturar o sistema Herança para abstração e implementação Detalhes de implementação são escondidos do cliente © 2003 Jaelson Castro Padrões de Projeto 64 Padrão Decorator Intenção Anexa dinamicamente responsabilidades adicionais a um objeto. Provê uma alternativa flexível ao uso de herança como modo de estender funcionalidade. Motivação © 2003 Jaelson Castro Algumas vezes se quer adicionar responsabilidades a um objeto, mas não à sua classe. Acontece, por exemplo, com criação de interfaces gráficas, quando se deseja acrescentar uma borda a um componente qualquer ou um scrollbar a uma área de texto. Uma forma de se acrescentar responsabilidades é através de herança, mas isto torna o projeto inflexível, pois a escolha da borda é definida em tempo de compilação. Neste caso o cliente não pode controlar como, onde e quando decorar o componente com uma borda. Uma abordagem mais flexível é inserir o componente em outro objeto que adiciona a borda, um Decorator. Padrões de Projeto 65 Padrão Decorator Estrutura e Participantes Component VisualComponent operation() TextView ConcreteComponent Decorator operation() operation() component ConcreteDecoratorA ConcreteDecoratorB operation() operation() addedBehavior() addedState BorderDecorator © 2003 Jaelson Castro component.operation(); super.operation(); addedBehavior(); ScrollDecorator Padrões de Projeto 66 Padrão Decorator Aplicabilidade Use o padrão Decorator: Para adicionar responsabilidades a objetos individuais de forma dinâmica e transparente, sem afetar outros objetos Para responsabilidades que podem ser removidas Quando extensão através de herança é impraticável. Algumas vezes uma grande quantidade de extensões independentes são possíveis e seria necessário um imenso número de subclasses para suportar cada combinação possível entre elas. Conseqüências © 2003 Jaelson Castro Mais flexibilidade que herança Evita incorporação forçada de comportamentos desnecessários Padrões de Projeto 67 Padrão Facade Intenção Prover uma interface unificada para o conjunto de interfaces de um subsistema. Define uma interface de alto nível que faz um subsistema mais fácil de usar. Motivação © 2003 Jaelson Castro Estruturar um sistema em subsistemas contribui para reduzir sua complexidade. A dependência entre subsistemas pode ser minimizada através do uso de um objeto Fachada, o qual provê uma interface única e uniforme para as diversas funcionalidades de um subsistema. Padrões de Projeto 68 Padrão Facade Estrutura e Participantes Client subsystem classes Compilador Facade Scanner Parser Token © 2003 Jaelson Castro Padrões de Projeto 69 Padrão Facade Aplicabilidade Use o Padrão Facade quando: © 2003 Jaelson Castro Você quer prover uma interface simplificada para um subsistema complexo. Um Facade pode prover uma visão simples e default do subsistema, suficiente para a maioria dos clientes Existem muitas dependências entre clientes e classes da implementação. O Facade reduz esta dependência e promove independência e portabilidade Você quer criar sistemas em camadas. Um Facade provê o ponto de entrada para cada camada (nível) do subsistema. Padrões de Projeto 70 Padrão Facade Conseqüências Protege os clientes dos componentes do subsistema Promove acoplamento fraco entre o subsistema e seus clientes Reduz dependências de compilação Facilita a portabilidade do sistema Não evita que aplicações possam acessar diretamente as subclasses do sistema, se assim o desejarem. © 2003 Jaelson Castro Padrões de Projeto 71 Padrão Flyweight Intenção Usar compartilhamento para suportar uma grande quantidade de objetos de baixa granularidade de forma eficiente. Motivação © 2003 Jaelson Castro Algumas aplicações podem se beneficiar do uso de objetos em seu projeto, mas uma implementação ingênua pode tornar este uso proibitivamente dispendioso (principalmente o consumo de memória) Um Flyweight é um objeto compartilhado que pode ser usado em múltiplos contextos simultaneamente, porque possui um estado intrínseco (comum a todos os contextos) e se utiliza de vários estados extrínsecos (particulares a cada contexto onde o Flyweight é usado). Clientes são responsáveis por passar o estado extrínseco ao Padrões de Projeto 72 Flyweight quando vão utilizá-lo. Padrão Flyweight Estrutura e Colaboradores imp FlyweightFactory Flyweight getFlyweight(key) Operation(extrinsincState) Glyph If (flyweight[key] exists) { return existing flyweight } else { create new flyweight; add it to pool of flyweights; return the new flyweight; } Client © 2003 Jaelson Castro ConcreteFlyweight UnsharedConcreteFlyweight Operation(extrinsincState) Operation(extrinsincState) intrinsincState allState Character Row, Collumn Padrões de Projeto 73 Padrão Flyweight Aplicabilidade Use o Padrão Flyweight quando TODAS as condições abaixo forem verdadeiras: © 2003 Jaelson Castro A aplicação usa uma grande quantidade de objetos Custos de armazenamento são altos, por causa da imensa quantidade de objetos Parte considerável do estado do objeto pode se tornar extrínseco Uma vez que o estado extrínseco é removido, muitos agrupamentos de objetos podem ser substituídos por uma quantidade consideravelmente menor de objetos compartilhados A aplicação não depende de identidade de objetos. Visto que flyweights podem ser compartilhados, testes de identidade irão retornar true para objetos conceitualmente distintos. Padrões de Projeto 74 Padrão Flyweight Conseqüências Custos de run-time associados com transferência, busca e/ou computação do estado extrínseco. Tais custos são compensados pela economia em uso de memória, à medida que mais flyweights são criados. Redução de consumo de memória é função de: © 2003 Jaelson Castro redução do número total de instâncias resultantes do compartilhamento quantidade de estado intrínseco por objeto Se o estado extrínseco é armazenado ou Padrões de Projeto 75 Padrão Proxy Intenção Prover um representante para outro objeto de modo a controlar o acesso a este Motivação Várias razões para controlar acesso a um objeto, como por exemplo: © 2003 Jaelson Castro deferir o custo de criação e inicialização para o momento de uso (objetos sob demanda); Prover um representante local para um objeto remoto; Proteger o objeto original. Padrões de Projeto 76 Padrão Proxy Estrutura e Colaboradores Subject Client request() RealSubject Proxy request() ... request() ... Image © 2003 Jaelson Castro Graphic realSubject.request(); ImageProxy Padrões de Projeto 77 Padrão Proxy Conseqüências Acrescenta um nível de indireção adicional © 2003 Jaelson Castro Padrões de Projeto 79 Padrão Comportamental Preocupam-se com algoritmos e a atribuição de responsabilidades entre objetos. Descrevem padrões de comunicação entre os objetos. © 2003 Jaelson Castro Padrões de Projeto 80 Alguns Exemplos De Objeto Baseados no uso de composição State, Chain of Responsability, Command, Mediator, Observer, Strategy, Visitor, Iterator, Memento De Classe © 2003 Jaelson Castro Baseados no uso de herança Template Method Interpreter Padrões de Projeto 81 Padrão Comportamental: State Nome: State Problema: Um objeto exibe um comportamento diferente quando seu estado interno muda, fazendo o objeto parecer ter mudado a classe em tempo de execução. Contexto: Ema algumas aplicações um objeto pode ter o comportamento complexo que seja dependente do seu estado. A resposta para uma mensagem específica varia de acordo com o estado do objeto. © 2003 Jaelson Castro Padrões de Projeto 82 Padrão Comportamental: State Forças: O objeto tem comportamento complexo que deve ser dividido em elementos menos complexos. Uma ou mais operações têm comportamento que variam de acordo com o estado do objeto. Tipicamente a operação teria muitas sentenças condicionais dependentes do estado. Uma abordagem é ter operações públicas separadas para cada estado, mas objetos cliente precisam saber o estado do objeto para poderem chamar a operação adequada © 2003 Jaelson Castro Padrões de Projeto 83 Padrão Comportamental: State Solução: Separar o estado dependente do comportamento do objeto original e alocar este comportamento para um série de outros objetos, um para cada estado. Estes objetos estado têm apenas responsabilidade para o comportamento daquele estado. Context operation( ) State {abstract} operation( ) ConcreteStateA Operation( ) © 2003 Jaelson Castro ConcreteStateB Operation( ) Padrões de Projeto 84 Participantes do Padrão State Contexto define a interface de interesse para clientes mantém uma instância de uma subclasse ConcreteState que define o estado corrente Estado define uma interface para encapsulamento do comportamento associado com um estado específico do Contexto Subclasses ConcreteState cada subclasse implementa um comportamento associado com um estado do Contexto © 2003 Jaelson Castro Padrões de Projeto 85 Padrão Comportamental: State Vantagens: © 2003 Jaelson Castro Comportamento do estado é localizado e o comportamento para diferentes estados é separado. Isto facilita qualquer modificação do comportamento do estado, em particular a adição de estados extra. Transições de estado são explícitas. O objeto estado que está ativo, indica o estado atual do objeto Contexto. Padrões de Projeto 86 Padrão Comportamental: State Desvantagens: Objeto estado pode ser criado e removido quando o objeto Contexto muda o estado, introduzindo assim um overhead no processamento. O uso do padrão estado introduz pelo menos uma mensagem extra, a mensagem da classe Contexto para classe Estado, adicionando assim mais overhead no processamento. © 2003 Jaelson Castro Padrões de Projeto 87 Padrão State : Um Sistema de Biblioteca Copy CheckOut LoanStatus {abstract} CheckOut OnLoan Available CheckOut CheckOut •As subclasses concretas definem o método de acordo com o estado que elas representam Available::CheckOut (book; OnLoan::CheckOut (book; user) user) //Check out book to a //Error: ‘Book already out’ user © 2003 Jaelson Castro Padrões de Projeto 88 Padrão State : Agate © 2003 Jaelson Castro Padrões de Projeto 89 Padrão Chain of Responsability Intenção Evita o acoplamento do remetente de uma solicitação ao seu receptor, ao dar a mais de um objeto a oportunidade de tratar uma solicitação. Encadeia os objetos receptores, passando a solicitação ao longo da cadeia até que um objeto a trate. Motivação © 2003 Jaelson Castro Help sensível ao contexto: O usuário pode obter ajuda em qualquer parte da interface simplesmente pressionando o botão do mouse sobre ela. A ajuda depende da parte selecionada e do seu contexto. Padrões de Projeto 90 Chain of Responsability Estrutura do Padrão HelpHandler Handler HandleRequest() client ConcreteHandler1 HandleRequest() PrintButton © 2003 Jaelson Castro sucessor ConcreteHandler2 HandleRequest() PrintDialogue Padrões de Projeto 91 Chain of Responsability Participantes Handler ConcreteHandler Define uma interface para tratar solicitações. Implementa o elo ao sucessor. Trata de solicitações pelas quais é responsável. Pode acessar o seu sucessor. Se o ConcreteHandler pode tratar a solicitação, ele o faz; caso contrário, ele a repassa para o seu sucessor. Client © 2003 Jaelson Castro Inicia a solicitação para um objeto ConcreteHandler da cadeia. Padrões de Projeto 92 Chain of Responsability Aplicabilidade Use o Padrão Chain of Responsability quando: © 2003 Jaelson Castro Mais de um objeto pode tratar uma solicitação e o objeto que a tratará não é conhecido a priori. O objeto que trata a solicitação deve ser escolhido automaticamente; Você quer emitir uma solicitação para um dentre vários objetos, sem especificar explicitamente o receptor; O conjunto de objetos que pode tratar uma solicitação deve ser especificado dinamicamente. Padrões de Projeto 93 Chain of Responsability Colaborações Quando um cliente emite uma solicitação, a mesma se propaga ao longo da cadeia até que um objeto ConcreteHandler assume a responsabilidade de tratá-la. © 2003 Jaelson Castro Padrões de Projeto 94 Chain of Responsability Conseqüências Acoplamento reduzido entre cliente e receptor Flexibilidade na atribuição de responsabilidades a objetos. A cadeia pode ser modificada em tempo de execução A solicitação não é garantida de ser tratada © 2003 Jaelson Castro Padrões de Projeto 95 Padrão Iterator Intenção Fornecer um meio de acessar, sequencialmente, os elementos de um objeto agregado sem expor a sua representação interna. Motivação List Count() Append(Element) Remove(Element) ... © 2003 Jaelson Castro list ListIterator First() Next() IsDone() CurrentItem() Padrões de Projeto 96 Padrão Iterator Estrutura Aggregate CreateIterator() client ConcreteAggregate CreateIterator() Iterator First() Next() IsDone() CurrentItem() ConcreteIterator Return new ConcreteIerator(this) © 2003 Jaelson Castro Padrões de Projeto 97 Iterator Participantes Iterator ConcreteIterator Implementa a interface de Iterator. Mantém o controle da posição corrente no percurso do agregado. Aggregate Define uma interface para acessar e percorrer elementos. Define uma interface para a criação de um objeto Iterator. ConcreteAggregate © 2003 Jaelson Castro Implementa a interface de criação do Iterator para retornar uma instância do ConcreteIterator apropriado. Padrões de Projeto 98 Padrão Iterator Colaborações Um ConcreteIterator mantém o controle do objeto corrente no agregado e pode computar o objeto sucessor no percurso. © 2003 Jaelson Castro Padrões de Projeto 99 Padrão Iterator Aplicabilidade Para acessar os conteúdos de um objeto agregado sem expor a sua representação interna; Para fornecer uma interface uniforme que percorra diferentes estruturas agregadas (iteração polimórfica). © 2003 Jaelson Castro Padrões de Projeto 100 Padrão Observer Intenção Definir uma dependência um-para-muitos entre objetos, de maneira que quando um objeto muda o seu estado todos os seus dependentes são notificados e atualizados automaticamente. Motivação © 2003 Jaelson Castro Separação das classes de apresentação das classes de aplicação (ex: visualizadores para C e Java de árvores sintáticas) Padrões de Projeto 101 Padrão Observer Estrutura Subject Attach(Observer) Dettach(Observer) Notify() ConcreteSubject GetState() SetState() subjectState © 2003 Jaelson Castro observers Observer Update() For all o in observers { o.Update } subject return subjectState; ConcreteObserver Update() observerState observerState = subject.GetState; Padrões de Projeto 102 Padrão Observer Participantes Subject Observer Conhece os seus observadores. Um número qualquer de objetos Observer pode observar um subject. Fornece uma interface para acrescentar e remover objetos observers. Define uma interface de atualização para objetos que devem ser notificados sobre mudanças em um Subject. ConcreteSubject © 2003 Jaelson Castro Armazena estados de interesse para objetos ConcreteObserver. Envia uma notificação para os seus observadores quando seu estado muda. Padrões de Projeto 103 Padrão Observer Participantes ConcreteObserver © 2003 Jaelson Castro Mantém uma referência para um objeto ConcreteSubject. Armazena estados que devem permanecer consistentes com os do Subject. Implementa a interface de atualização de Observer, para manter seu estado consistente com o do subject. Padrões de Projeto 104 Padrão Observer Colaborações O ConcreteSubject notifica seus observadores sempre que ocorrer uma mudança que pode tornar inconsistente o estado deles com o seu próprio. Após ter sido informado de uma mudança no subject concreto, um objeto ConcreteObserver pode consultar o subject para obter informações. O ConcreteObserver usa esta informação para reconciliar o seu estado com aquele do subject. © 2003 Jaelson Castro Padrões de Projeto 105 Padrão Observer Aplicabilidade Quando uma abstração tem dois aspectos, um dependente do outro. Encapsulando esses aspectos em objetos separados, permite-se variá-los e reutilizá-los independentemente. Quando uma mudança em um objeto exige mudanças em outros, e você não sabe quantos objetos necessitam ser mudados. © 2003 Jaelson Castro Padrões de Projeto 106 Padrões GOF 23 Criação (5) Estrutura (7) Comportamento (11) © 2003 Jaelson Castro Padrões de Projeto 107 Padrões de Criação: Objeto Único (Singleton) Fábrica Abstrata (Abstract Factory) Oferece uma interface para criar famílias de objetos relacionados sem especificar suas classes concretas. Construtor (Builder) Garante que uma classe tenha apenas uma única instância, e oferece um ponto global para acessá-la. Separa a construção de um objeto complexo de sua representação, então o mesmo processo de construção pode criar diferentes representações. Protótipo (Prototype) Especifica os tipos de objetos para criar usando uma instância prototípica, e cria novos objetos copiando deste protótipo. © 2003 Jaelson Castro Padrões de Projeto 108 Padrões de Criação: Classe Método Factory Define uma interface para criação de um objeto, mas deixa a subclasse decidir que classe instancia. Permite a classe retardar a instanciação da subclasse. © 2003 Jaelson Castro Padrões de Projeto 109 Padrões Estruturais: Objeto Adaptador (Adapter) Ponte (Bridge) Converte a interface de uma classe em outra interface que os clientes esperam. Desacopla uma abstração da sua implementação, as duas podem variar independentemente (herança em tempo de execução) Composto (Composite) Compõe objetos em três estruturas para representar hierarquias parte-todo. Composto permite que clientes tratem tanto os objetos individuais quanto as composições de objetos uniformemente. © 2003 Jaelson Castro Padrões de Projeto 110 Padrões Estruturais: Objeto Decorador (Decorator) Fachada (Façade) Oferece uma interface unificada para um conjunto de interfaces de um subsistema. Peso Mosca (Flyweight) Anexa responsabilidades adicionais para um objeto dinamicamente. Usa compartilhamento para apoiar um grande número de objetos de fina granularidade eficientemente. Proxy © 2003 Jaelson Castro Oferece lugar de acesso para outro objeto controlar o acesso. Padrões de Projeto 111 Padrões Estruturais: Classe Adaptador (Adapter) Converte a interface de uma classe para outra interface que os clientes esperam. Base de Template (Template Base) Usa classes base do template para especificar associações. © 2003 Jaelson Castro Padrões de Projeto 112 Padrões Comportamentais: Objeto Cadeia de Responsabilidade Evita o acoplamento do emissor de um pedido ao seu receptor através da chance de mais de um objeto em mudar seu pedido Observador (Observer) Quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente. © 2003 Jaelson Castro Padrões de Projeto 113 Padrões Comportamentais: Objeto (cont.) Iteração (Iterator) Oferece uma maneira para acessar os elementos de um objeto agregado sequencialmente sem expor a sua representação. Mediador (Mediator) Define um objeto que encapsula como um conjunto de objetos que interagem entre si. © 2003 Jaelson Castro Padrões de Projeto 114 Padrões Comportamentais: Objeto (cont.) Comando Encapsula a requisição como um objeto. “Memento” Captura e externaliza um estado interno do objeto para que este estado possa ser recuperado depois. Estado Permite que um objeto altere seu comportamento quando seu estado interno muda. © 2003 Jaelson Castro Padrões de Projeto 115 Padrões Comportamentais: Objeto (cont.) Estratégia Visitante © 2003 Jaelson Castro Define uma família de algoritmos, encapsula cada um, e torna-os intercambiáveis. Representa uma operação a ser realizada para os elementos da estrutura de um objeto. Padrões de Projeto 116 Padrões Comportamentais: Classe Interpretador Dada uma linguagem, define uma representação para sua gramática com um interpretador que usa a representação para interpretar sentenças na linguagem. Template de método Permite que subclasses redefinam certos passos de um algoritmo sem alterar a estrutura do algoritmo. © 2003 Jaelson Castro Padrões de Projeto 117 Usando Padrões Existe um padrão que trata um problema similar? O contexto do padrão é consistente com o problema real? As conseqüências do uso de padrão são aceitáveis? © 2003 Jaelson Castro Padrões de Projeto 118 Usando Padrões (cont.) O padrão dispara uma solução alternativa que pode ser mais aceitável? Existe uma solução mais simples? Existem algumas restrições de conflito que sejam impostas pelo ambiente de software que está sendo usado? © 2003 Jaelson Castro Padrões de Projeto 119 Catálogo de Padrões Padrões colecionados num catálogo precisam ser agrupados. Projetistas descobrindo novos padrões precisam considerar onde o seu novo padrão se encaixa no catálogo. Todos os usuários precisam ser atualizados no conteúdo do catálogo © 2003 Jaelson Castro Padrões de Projeto 120 Armazenando e Procurando Padrões Manutenção da documentação de padrões Procura de facilidades disponíveis Agrupamento de padrões Publicação de padrões disponíveis Uso de fontes, tipos, ênfase, etc. © 2003 Jaelson Castro Padrões de Projeto 121 Benefícios do Uso de Padrões Eles oferecem um mecanismo para reusar soluções genéricas. Eles oferecem um vocabulário para discutir o domínio do problema no mais alto nível de abstração, tornando mais fácil considerar aspectos micro arquiteturais. © 2003 Jaelson Castro Padrões de Projeto 122 Perigos do Uso de Padrões Algumas pessoas acreditam que o uso de padrões possa limitar a criatividade. O uso de padrões de uma maneira descontrolada pode originar projetos carregados. Desenvolvedores: © 2003 Jaelson Castro Precisam de tempo para entender os catálogos de padrões relevantes Precisam de fácil acesso para catálogos relevantes Precisam ser treinados no uso de padrões Padrões de Projeto 123 Leituras Adicionais Gamma E, Helm R, Johnson R and Vlissides J. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley 1994. © 2003 Jaelson Castro Padrões de Projeto 124