Padrões de Projeto Alcides Calsavara http://www.ppgia.pucpr.br/ ~alcides
Padrões de Projeto
Alcides Calsavara
http://www.ppgia.pucpr.br/~alcides
Referências BibliográficasDesign Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma e outros (GoF), Addison-Wesley, 1995.Patterns in Java: a catalog of reusable design patterns illustraded in UML, Volume 1. Mark Grand, John Wiley & Sons, 1998.Projeto de Software: da programação à arquitetura (Software design: from programming to architecture). Eric Braude, John Wiley & Sons, 2004.
Design Pattern(Padrão de Projeto)
Descrição de um problema recorrente, de forma genérica.Descrição de uma solução também genérica, que deve ser adaptada de acordo com o contexto em que o problema se manifesta.
Objetivos de projetoReusabilidade, flexibilidade e manutenibilidade
reutilize projetos flexíveis mantenha o código em um nível geral minimize dependência de outras classes
Robustez reutilize projetos seguros reutilize partes robustas
Suficiência e correção modularize o projeto reutilize partes confiáveis
Vantagens no uso de DPEvita a redescoberta de soluçõesPropicia o uso de soluções corretasMelhora a qualidade do softwareMelhora a confiabilidade do softwareProvê uma linguagem comum entre desenvolvedoresReduz o volume de documentaçãoEconomiza esforço e tempo de desenvolvimento e manutençãoConduz ao bom uso de orientação a objetos
Exemplo de Problema Recorrente : Composição
Em um sistema de arquivos, existem arquivos e pastas (diretórios), sendo que todo arquivo está contido em uma pasta e toda pasta pode conter arquivos e também outras pastas.Em um documento, existem caracteres e imagens como elementos básicos, e páginas, colunas, frames e linhas de texto como elementos compostos, sendo que todo elemento básico está contido em um elemento composto e todo elemento composto pode conter elementos básicos e também outros elementos compostos.
Composição emSistema de Arquivos
ComponenteSistemaArquivos
Arquivo Pasta
listar ( ) {abstract}
listar ( )listar ( )
tamanho
tipo
0..*
Composição emDocumento
ElementoDocumento
Caráter Imagem ElementoCompostoDocumento
Documento Página Coluna Frame LinhaTexto
0..*
Composição:Solução Genérica 1 (GoF)
Component
Operation()Add(Component)Remove(Component)GetChild(int)
Composite
Operation()Add(Component)Remove(Component)GetChild(int)
Leaf
Operation()
0..*Client
Composição:Solução Genérica 2 (M. Grand)
AbstractComponent
operation()
ConcreteComponent1
operation()
ConcreteComponent2
operation()
AbstractComposite
operation()add(AbstractComponent)remove(AbstractComponent)getChild(int)
ConcreteComposite1
operation()add(AbstractComponent)remove(AbstractComponent)getChild(int)
ConcreteComposite2
operation()add(AbstractComponent)remove(AbstractComponent)getChild(int)
..
....
0..*
Categorias de padrões (GoF)
CRIACIONAIS: criar uma coleção de objetos de maneira flexível ou restrita.ESTRUTURAIS: representar uma coleção de objetos relacionados.COMPORTAMENTAIS: captar comportamento em uma coleção de objetos.
Padrões de projeto criacionais
FábricaFábrica AbstrataProtótipoObjeto Unitário
Padrões de projeto estruturais
CompostoDecoradorAdaptadorFachada
Padrões de projeto comportamentais
ComandoIteradorInterpretadorObservadorGabarito
Documentação de um DP(Mark Grand)
NomeSinopseContextoForçasSoluçãoConseqüênciasImplementaçãoUso na API de JavaExemplo de códigoPadrões relacionados
Características de padrões de projeto
Pontos de vista: Estático: modelo de classes (do que
são feitos) Dinâmico: diagrama de seqüência ou
de estados (como funcionam)Níveis: Abstrato: descreve o núcleo do padrão Concreto: descreve as
particularidades de um caso
Padrões FundamentaisDelegation (Delegação)Interface (Interface)Marker Interface (Interface de Marcação)Immutable (Imutável)Proxy
Padrão Delegation (Delegação)
Permite estender e reusar a funcionalidade de uma classe através da escrita de classes adicionais com funcionalidades a mais que usam instâncias da classe original, a fim de prover a funcionalidade original.
Padrão Delegation – Exemplousando herança
Padrão Delegation – Exemplousando herança múltipla
Padrão Delegation – Exemplousando delegação
Padrão InterfaceMantém uma classe que usa dados e serviços providos por instâncias de outras classes independente dessas através do acesso a tais instâncias obrigatoriamente através de uma interface.
Padrão Interface – Exemplosem usar interface
Padrão Interface – Exemplousando interface
Padrão Interface – Exercício
Inclua um terceiro tipo de impressora (ImpressoraCanon) no diagrama de impressoras e sistema.
Padrão Marker Interface (Interface de Marcação)
Usa interfaces que não declaram qualquer método ou variável (atributo) para indicar propriedades semânticas de uma classe. Funciona muito bem para classes utilitárias que precisam determinar alguma coisa sobre objetos, sem entretanto precisar assumir que esses sejam instâncias de alguma classe em particular.
Padrão Marker Interface – Exemplo sem usar
Padrão Marker Interface – Exemplo usando
Padrão Marker Interface – Exercício
Inclua a interface de marcação Comprimível para a hierarquia de classes de documentos.
Padrões de projeto criacionais
FábricaFábrica AbstrataProtótipoObjeto Unitário
Padrão Factory Method (Fábrica)
Permite que uma classe genérica (escrita para ser reusada) instancie outras classes sem que seja dependente de tais classes, isto é, sem que faça menção explícita a essas. A classe genérica se mantém independente das classes que instancia através da delegação para um outro objeto da escolha de qual classe instanciar e somente refere-se ao objeto então criado através de uma interface comum.Permite criar objetos desejados utilizando métodos que retornam os objetos.
Padrão Factory Method – Geral
Padrão Factory Method – Exemplo
Padrão Abstract Factory(Fábrica Abstrata)
Kit ou ToolkitPermite a criação de instâncias de um conjunto de classes abstratas relacionadas a partir de respectivo um conjunto de classes concretas. Pode ser muito útil quando se precisa trabalhar com uma variedade de entidades externas complexas.Permite criar famílias coordenadas de objetos em tempo de execução, escolhidos a partir de um conjunto de estilos.
Padrão Abstract Factory - Geral
Padrão Abstract Factory - Exemplo
Padrão Prototype (Protótipo)
Permite criar os objetos de um tipo clonando um protótipo. Permite um objeto criar objetos customizados sem saber suas classes exatas e sem saber detalhes sobre como fazer tal criação.Funciona através do fornecimento de objetos protótipos para um objeto que então solicita de tais protótipos a criação de cópias deles próprios.
Padrão Protótipo: Geral
Padrão Protótipo: Exemplo
Padrão Singleton (Objeto Unitário)
Assegura que uma classe tenha exatamente uma instanciação, acessível por toda aplicação.Garante que apenas uma e somente uma instância de uma certa classe é criada.Todos os objetos que usam uma instância da classe usam a mesma instância.
Padrão Singleton - Geral
Padrão Composite (Composição)
Recursive Composition PatternPermite representar uma árvore de objetos tal que o acesso seja uniforme. Permite construir objetos complexos através de uma composição recursiva que define uma árvore de objetos. Todos os objetos são acessados de maneira consistente e homogênea, pois todos possuem uma superclasse ou uma interface comum.
Padrão Composite (Composição)
Há um objeto complexo que deve ser decomposto numa hierarquia “parte-todo” de objetos.Deseja-se minimizar a complexidade numa hierarquia parte-todo de objetos através da minimização do número de tipos diferentes de filhos que precisam ser explicitamente conhecidos dos objetos da árvore.
Façade (Fachada )Fornece uma interface para um pacote de classes.Regula a comunicaçãoa com os objetos de um pacote (componente).Clientes interagem com uma única classe de um pacote.A estrutura Fachada está na forma de delegação.Permite gerenciar arquiteturas de software envolvendo grandes números de classes.
Fachada: Geral
Fachada: Exemplo
Padrão Iterator (Iterador)Define uma interface que declara métodos para o acesso seqüencial aos objetos de uma coleção.Uma classe (cliente) que acessa a coleção somente através de uma interface desse tipo permanece independente da classe que implementa a interface.
Padrão Iterador: Geral
Padrão Iterador: Exemplo
Padrão Command (Comando)
Encapsula comandos em objetos tal que é possível controlar sua seleção e seqüenciamento, enfileirá-los, desfazê-los (undo ), isto é, manipulá-los de forma geral.Permite tornar a execução de operações mais flexível (ex: desfazer).
Padrão Comando – Geral
Padrão Comando - Exemplo
Padrão Observer (Observador)
Permite que objetos registrem dinamicamente suas dependências de outros objetos.Um objeto especial notificará os objetos dependentes sempre que os objetos dos quais dependem sofrerem alteração de estado.Permite atualizar um conjunto de objetos quando um certo objeto sofrer modificação.
Padrão Observador - Geral
Padrão Observador - Exemplo
Padrão Adapter (Adaptador)
Permite que uma aplicação utilize funcionalidades externas.Uma classe Adapter implementa uma interface conhecida dos clientes e permite acesso a instâncias de uma classe não conhecida dos clientes.Um objeto Adapter provê a funcionalidade prometida por uma interface sem fixar a classe que de fato implementa a interface.
Padrão Adapter - Geral
Padrão Adapter – Exemplo 1
Padrão Adapter – Exemplo 2
Decorator (Decorador)Permite adicionar e remover responsabilidades de uma classe em tempo de execução (dinamicamente).Alternativa flexível a generalização/especialização para extensão de funcionalidade.
Decorator - Geral
Decorator – Exemplo 1
Decorator – Exemplo 2
Padrão Strategy (Estratégia)
Encapsula algoritmos relacionados em classes que são subclasses de uma classe comum.Permite a seleção de algoritmo variar por objeto e também no decorrer do tempo.
Padrão Strategy – General
Padrão Strategy – Exemplo 1
Padrão Strategy – Exemplo 2
Interpreter (Interpretador)Permite analisar sintaticamente uma expressão.
Interpreter - Geral
Interpreter - Exemplo
Padrão Guarded Suspension
Suspende a execução de uma chamada de método até que uma pré-condição seja satisfeita.
Exemplo: Guarded Suspensionclass Conta { private double saldo; public synchronized void saque(double v) { while ( saldo < v ) { try { wait( ); } catch ( InterruptedException e ) { } } saldo = saldo – v; }
public synchronized void deposito(double v) { saldo = saldo + v; notifyAll( ); }}
Padrão Producer-Consumer
Coordena a produção e o consumo assíncronos de objetos de informação.
Exemplo: Producer-Consumerclass Queue{ private Vector data = new Vector( ); // fila de objetos synchronized public void put( Object obj ) { data.add( obj ); // insere o objeto na fila notify( ); } synchronized public Object get( ) { while ( data.size( ) == 0 ) // enquanto fila vazia { try { wait( ); } catch ( InterruptedException e ) { } } Object obj = data.elementAt( 0 ); // primeiro da fila data.removeElementAt( 0 ); return obj; }}