Padrões Comportamentais
Formulário para Descrição de Padrões Nome e Classificação Intenção Também Conhecido Como Motivação Aplicabilidade Estrutura Participantes Colaboradores Conseqüências Implementação Exemplo de Código Usos Conhecidos Padrões Relacionados
Notação de Classes e Objetos referencia objeto ClasseAbstrata agrega um ClasseConcreta operaçãoabstrata() cria muitos SubclasseConcreta1 operação() variáveldeinstância SubclasseConcreta2 pseudo código umobjeto referênciaaobjeto outroobjeto variáveldeinstância
Diagrama de Interação de Objetos umobjeto outroobjeto TEMPO operação ativa sobre o objeto outroobjeto = new Objeto() (instanciação) outroobjeto.método() this.método()
Padrões Comportamentais(1/2) Tratam de algoritmos e como atribuir responsabilidades entre objetos ChainOf Command Interpreter Responsibility exec & new Iterator Mediator exec() Memento a * b c
Padrões Comportamentais(2/2) Tratam de algoritmos e como atribuir responsabilidades entre objetos State Strategy Observer(s) 30%, 20%, 10%, 50% 60% a() b() TemplateMethod() a(..);... b(..); Visitor Visitor Visitor a() b()
Padrões Comportamentais Enquanto se concentram apenas na forma como os objetos são conectados, criam complexos fluxos de controle que são difíceis de seguir em runtime. De Classe baseados no uso de herança De Objeto baseados no uso de composição
Padrões Comportamentais Chain of Responsibility - Encadeamento de Atendentes Command - Comando Interpreter - Interpretador Iterator - Iterador Mediator - Mediador Memento - Lembrança Observer - Observador State - Estado Strategy - Estratégia Template Method - Esqueleto de Método Visitor - Visitante
Padrões Comportamentais Chain of Responsibility - Encadeamento de Atendentes (Objeto) Evita acoplamento entre solicitantes e atendentes permitindo que mais de um objeto tenha chance de tratar da solicitação. Encadeia os atendentes e passa a solicitação através desta cadeia até que algum deles a trate. Command - Comando (Objeto) Encapsula uma solicitação no interior de um objeto, permitindo que se parametrize clientes com diferentes solicitações, filas ou registros de solicitações, suportando ainda o cancelamento de solicitações. Interpreter - Interpretador (Classe) Dada uma linguagem, cria uma representação para a gramática da linguagem, juntamente com um interpretador que utilizar esta representação para interpretar sentenças na linguagem.
Padrões Comportamentais Iterator - Iterador (Objeto) Provê uma forma de acessar seqüencialmente os elementos de um agregado de objetos, sem expor a representação interna deste agregado. Mediator - Mediador (Objeto) Define um objeto que encapsula o modo como um conjunto de objetos interage. Promove um acoplamento fraco entre objetos, evitando que referenciem diretamente um ao outro e permitindo que se possa variar a interação entre eles de modo independente. Memento - Lembrança (Objeto) Sem violar encapsulamento, captura e armazena externamente o estado de um objeto, de modo que o estado anterior de um objeto possa ser posteriormente restaurado.
Padrões Comportamentais Observer - Observador (Objeto) Define uma dependência 1- para-n entres objetos, de modo que quando o estado de um objeto é alterado todos seus dependentes são notificados e atualizados automaticamente. State - Estado (Objeto) Permite que um objeto altere seu comportamento quando seu estado interno se modifica. O objeto parecerá ter mudado de classe. Strategy - Estratégia (Objeto) Define uma família de algoritmos, encapsula cada um, e os faz inter-cambiáveis. Permite que o algoritmo varie independentemente dos clientes que o utilizam.
Padrões Comportamentais Template Method - Esqueleto de Método (Classe) Define o esqueleto de um algoritmo através de uma operação, deixando que subclasses refinem o restante do algoritmo. Permitem que subclasses redefinam certos aspectos de um algoritmo sem modificar a estrutura do algoritmo. Visitor - Visitante (Objeto) Representa uma operação a ser executada sobre os elementos da estrutura de um objeto. Visitantes permitem que se definam novas operações sem modificar as classes dos elementos sobre as quais ele atua.
Chain of Responsibility ChainOf Responsibility
Padrão Chain of Responsibility Intenção Evita acoplamento entre solicitantes e atendentes permitindo que mais de um objeto tenha chance de tratar da solicitação. Encadeia os atendentes e passa a solicitação através desta cadeia até que algum deles a trate. Motivação Considere, por exemplo, a construção de um conjunto de helps (auxílios) em uma GUI. Suponha que o usuário possa obter auxílio a partir de qualquer parte da interface pressionnando, F1. O help deve então ser sensível ao contexto onde foi ativado. Nestes casos torna-se natural criar vários níveis de auxílio, se aplicando da situação mais específica à mais geral. Quando o contexto mais específico não dispuser de auxílio, o contexto de auxílio imediatamente superior deve ser ativado. A idéia do padrão é facilitar o desacoplamento entre o solicitante (botão onde foi invocado o help) e o atendente (janela de help ativada)
Padrão Chain of Responsibility Estrutura e Participantes Client Handler handlerequest() successor ConcreteHandler1 handlerequest() ConcreteHandler2 handlerequest()
Padrão Chain of Responsibility Aplicabilidade Use o Padrão quando: Mais de um objeto pode tratar de um pedido, e o tratador de pedidos (handler) não é conhecido a priori. O handler deve ser buscado automaticamente de forma ascendente. Você quer emitir um pedido para um de vários objetos sem especificar o recebedor de forma explícita. O conjunto de objetos que pode tratar de um pedido deve ser configurado dinamicamente.
Padrão Chain of Responsibility Conseqüências Acoplamento reduzido Evita que um objeto (client) seja forçado a tomar conhecimento do outro (handler) O objeto só precisa saber que o pedido foi tratado apropriadamente A estrutura da cadeia não precisa ser conhecida Flexibilidade na atribuição de responsabilidades para objetos (subclasses, alteração dinâmica da cadeia) Sucesso no tratamento do pedido não é garantido
Padrão Chain of Responsibility Exercícios Observe os trechos de código das próximas 2 páginas e veja como funciona a Chain of Responsibility do tratamento de eventos no AWT 1.0. Veja também detalhes do código fonte das classes Component Método handleevent() e suas várias ramificações.
Class Component {.. public boolean postevent(event e) { if (handleevent(e)) { e.consume(); return true; } Component parent = this.parent;... if (parent!= null) {... if (parent.postevent(e)) { e.consume(); return true; } } return false; } }
public class BancoApplet extends Applet { Button clientesbutton, contasbutton, creditebutton, debitebutton; public boolean handleevent(event evt) { if (evt.id == Event.ACTION_EVENT) { if (evt.target == clientesbutton) {... } else if (evt.target == contasbutton) {... } else if (evt.target == creditebutton) {... } else if (evt.target == debitebutton) {... } } else { return super.handleevent(evt); } } }
Command Command exec new exec()
Padrão Command Intenção Encapsula uma solicitação no interior de um objeto, permitindo que se parametrize clientes com diferentes solicitações, filas ou registros de solicitações, suportando ainda o cancelamento de solicitações. Motivação Algumas vezes é necessário se fazer uma solicitação de serviço sem conhecimento algum do tipo de operação que está sendo requerida. Na construção de um menu, por exemplo. O padrão Command permite que um menu possa solicitar execução de pedidos sem conhecer a natureza destes pedidos, pois o próprio objeto encapsula os detalhes da execução do pedido.
Padrão Command Estrutura e Participantes Client Invoker Command execute() Receiver action() receiver ConcreteCommand execute() state receiver.action();
Padrão Command Colaborações areceiver aclient acommand aninvoker acommand = new Command StoreCommand(aCommand) action() execute()
Padrão Command Aplicabilidade Parametrizar objetos com uma ação a executar. Tal parametrização pode ser feita com funções de callback em linguagens imperativas. Comandos são um substituto orientado a objetos para callbacks. Especificar, armazenar e executar pedidos em momentos diferentes. Commands podem ser transferidos entre espaços de endereçamento e máquinas. Suportar undo A operação execute pode armazenar o estado para reverter os efeitos do próprio comando. Suportar logs de modificações Através da inclusão de undoable Commands em meio persistente. Estruturar um sistema em torno de operações de alto nível Constituídas internamente por várias operações primitivas. Facilidades para extensão do sistema.
Padrão Command Conseqüências Desacoplamento do objeto que invoca uma operação, do outro que executa esta operação Comandos são objetos, e como tal podem ser manipulados e refinados. Comandos podem ser compostos, criando MacroCommands É fácil criar novos comandos.
Padrão Command Exercícios Veja a capacidade de suporte à implementação dinâmica do padrão Command dentro dos pacotes java.lang e java.lang.reflect http://padct01:2001/java/lang/object.html Class java.lang.class Method[] getmethods(); Classe java.lang.reflect.method Object invoke(object target, Object[] args);
Interpreter Interpreter & a * b c
Padrão Interpreter Intenção Dada uma linguagem, cria uma representação para a gramática da linguagem, juntamente com um interpretador que utilizar esta representação para interpretar sentenças na linguagem. Motivação Quando uma estrutura de problema particular ocorre várias vezes, pode ser interessante representá-la através de uma sentença em uma linguagem simples, de modo a solucionar o problema através da construção de um interpretador para esta sentença. Em várias destas situações, em vez de construir algoritmos de interpretação manualmente, um interpretador genérico de expressões regulares pode solucionar o problema rapidamente. O padrão Interpreter usa classes para representar cada regra de uma gramática (expressão regular).
Padrão Interpreter Aplicabilidade Use o Padrão quando: A gramática é simples Para gramáticas complexas a hierarquia de classes se torna difícil de gerenciar. Neste caso, geradores de parsers são uma alternativa melhor. Eficiência não é uma questão crítica Código intermediário permite maior eficiência Expressões podem ser traduzidas para máquinas de estado finito Neste casos, o tradutor pode ser criado através de um interpreter
Padrão Interpreter Conseqüências É fácil modificar e estender a gramática Implementar a gramática também é fácil Gramáticas complexas são difíceis de manter Adicionar novas formas de interpretar expressões é simples
Iterator Iterator
Padrão Iterator (Cursor) Intenção Provê uma forma de acessar seqüencialmente os elementos de um agregado de objetos, sem expor a representação interna deste agregado. Motivação Objetos agregados como listas, tabelas hash, dicionários, etc, devem permitir que se acessem seus elementos de modo abstrato, sem que a representação interna de sua estrutura seja exposta Eventualmente também pode se desejar fazer duas travessias concorrentes sobre um mesmo objeto agregado. O padrão Iterator permite a criação de tais facilidades.
Padrão Iterator Estrutura e Participantes Aggregate createiterator() Client Iterator first() next() isdone() currentitem() ConcreteAggregate createiterator() ConcreteIterator Return new ConcreteIterator(this);
Padrão Iterator Aplicabilidade Use o Padrão Iterator quando: Se deseja acessar o conteúdo de um objeto agregado sem expor sua representação interna Se deseja suportar múltiplas travessias de um objeto agregado Se quer prover uma interface uniforme para atravessar diferentes estruturas agregadas. Suportar iteração polimórfica
Padrão Iterator Conseqüências Suporte a variações na maneira de se atravessar um objeto agregado (pre-order, pós-ordem, em-ordem) Simplificação da interface do agregado Mais de um cursor pendente sobre um agregado
Padrão Iterator Exercícios Observar o uso de agregados no pacote java.util. JDK 1.1 - Hashtable, Vector, Enumeration JDK 1.2 - Collection, Iterator IMPLEMENTAÇÕES - JDK 1.2 Hash Table Resizable Array Balanced Tree Linked List INTERFACES Set List Map HashSet TreeSet ArrayList HashMap TreeMap LinkedList
Mediator Mediator
Padrão Mediator Intenção Define um objeto que encapsula o modo como um conjunto de objetos interage. Promove um acoplamento fraco entre objetos, evitando que referenciem diretamente um ao outro e permitindo que se possa variar a interação entre eles de modo independente. Motivação
Padrão Mediator Estrutura e Participantes
Padrão Mediator Aplicabilidade Use o Padrão Mediator quando:
Padrão Mediator Conseqüências
Padrão Mediator Exercícios
Memento Memento
Padrão Memento Intenção Sem violar encapsulamento, captura e armazena externamente o estado de um objeto, de modo que o estado anterior de um objeto possa ser posteriormente restaurado. Motivação
Padrão Memento Estrutura e Participantes
Padrão Memento Aplicabilidade Use o Padrão Memento quando:
Padrão Memento Conseqüências
Padrão Memento Exercícios
Observer Observer(s) 30%, 20%, 10%, 50% 60%
Padrão Observer Intenção Define uma dependência 1-para-n entres objetos, de modo que quando o estado de um objeto é alterado todos seus dependentes são notificados e atualizados automaticamente.
Padrão Observer Motivação Suponha que você deseja fornecer várias visões distintas de um mesmo objeto que funciona como um repositório de dados Cada visão é criada por um objeto observador independente Caso cada observador seja diretamente conectado ao repositório, isto criará uma dependência do repositório com relação aos diferentes observadores, o que lhe reduzirá a reusabilidade e flexibilidade O padrão Observer descreve uma forma de manutenção destes relacionamentos de modo que observadores e repositórios sejam facilmente substituídos
Padrão Observer Estrutura e Participantes Subject attach(observer) detach(observer) notify() For all o in observers { o.update(); } ConcreteSubject getstate() subjectstate observers return subjectstate subject Observer update() ConcreteObserver update() observerstate observerstate = subject.getstate();
Padrão Observer Aplicabilidade Use o Padrão Observer em Algumas das Situações: Quando uma abstração apresenta dois aspectos, um dependente do outro. Encapsulando estes aspectos em objetos separados permite que você os varie e reutilize de forma independente Quando uma modificação em um objeto requer modificação em outros, e você não sabe (em tempo de programação) quantos objetos precisam ser modificados Quando um objeto deve ser apto a notificar outros objetos sem saber quem são estes objetos. Em outras palavras, quando você os quer fracamente acoplados
Padrão Observer Conseqüências Variação independente de observáveis e observadores É fácil adicionar observadores sem modificar o observável ou os outros observadores Suporte a comunicação broadcast Atualizações inesperadas (caso o processo de notificação seja simplificado)
Padrão Observer Exercícios Veja a implementação do padrão observer nos componentes do pacote AWT Destaque as diferenças entre o padrão original e a implementação do AWT
State State
Padrão State Intenção Permite que um objeto altere seu comportamento quando seu estado interno se modifica. O objeto parecerá ter mudado de classe. Motivação
Padrão State Estrutura e Participantes
Padrão State Aplicabilidade Use o Padrão State quando:
Padrão State Conseqüências
Padrão State Exercícios
Strategy Strategy
Padrão Strategy Intenção Define uma família de algoritmos, encapsula cada um, e os faz intercambiáveis. Permite que o algoritmo varie independentemente dos clientes que o utilizam. Motivação
Padrão Strategy Estrutura e Participantes
Padrão Strategy Aplicabilidade Use o Padrão Strategy quando:
Padrão Strategy Conseqüências
Padrão Strategy Exercícios
Template Method a() b() TemplateMethod() a(..);... b(..); a() b()
Padrão Template Method Intenção Define o esqueleto de um algoritmo através de uma operação, deixando que subclasses refinem o restante do algoritmo. Permitem que subclasses redefinam certos aspectos de um algoritmo sem modificar a estrutura do algoritmo. Motivação
Padrão Template Method Estrutura e Participantes
Padrão Template Method Aplicabilidade Use o Padrão TemplateMethod quando:
Padrão Template Method Conseqüências
Padrão Template Method Exercícios
Visitor Visitor Visitor Visitor
Padrão Visitor Intenção Representa uma operação a ser executada sobre os elementos da estrutura de um objeto. Visitantes possibilitam a definição de novas operações sem modificar as classes dos elementos sobre as quais ele atua. Motivação
Padrão Visitor Estrutura e Participantes
Padrão Visitor Aplicabilidade Use o Padrão Visitor quando:
Padrão Visitor Conseqüências
Padrão Visitor Exercícios
Uma Linguagem de Padrões para Programas OO Builder Salvando Estado da Operação Memento Adapter Proxy Decorator Strategy Prototype Criando Composições Adicionando Responsabilidades a Objetos Modificando Pele versus Entranhas Compartilhando Composições Flyweight Compartilhando Estratégias Compartilhando Estados Definindo Passos do Algoritmo State Configurar Fábrica Dinamicamente Iterator Enumerando Filhos Composite Adicionando Operações Definindo Gramática Interpreter Compartilhando Terminais Definindo Travessias Template Method Visitor Evitando Histerese Composto Usando Adicionando Operações Mediator Freqüentemente Usa Definindo a Cadeia Gerenciamento Complexo de Dependências Bridge Command Chain of Responsibility Observer Única Instância Singleton Abstract Factory Única Instância Implementada Usando Facade Factory Method
Fim