Design Patterns
A adoção dos padrões terá um efeito profundo e
duradouro sobre a forma de escrevermos programas
Ward Cunningham e Ralph Johnson
Design Patterns
•
Conhecer os princípios OO não faz de você um bom
projetista OO
•
Bons projetos OO são reutilizáveis, extensíveis e fáceis
de manter
•
Os padrões mostram como construir um projeto OO com
estas qualidades
•
Os padrões mostram soluções OO comprovadamente
eficientes
Design Patterns
•
Os padrões não são uma biblioteca de código. Eles
fornecem soluções genéricas para problemas de projeto.
Você tem de aplicá-los a sua aplicação específica.
•
Os padrões não são inventados, eles são descobertos
•
A maioria dos padrões aborda questões relativas a
proteção contra variações
•
A maioria dos padrões permite que parte do sistema varie
independentemente de todas as outras partes
Design Patterns
•
Freqüentemente tentamos extrair e encapsular aquilo que
varia em um sistema
•
Os padrões fornecem uma linguagem compartilhada que
permite maximizar o valor da sua comunicação com
outros desenvolvedores
Design Patterns
O Adaptador
O Adaptador
•
O Adaptador converte a interface de uma classe em uma
outra interface esperada pelo cliente.
•
O Adaptador permite que classes com interfaces
incompatíveis trabalhem em conjunto o que, de outra
forma, seria impossível
O Adaptador
O Adaptador
O Adaptador
O Adaptador
O código fonte
Ver arquivo Design Patterns\Adaptador\DadoNormal.java
Factory
O problema da Pizzaria: uma
implementação pobre
O código fonte
Ver arquivo
Design Patterns\Factory\ImplementacaoPobre\Pizza.java
Uma fábrica simples
O código fonte
Ver arquivo
Design Patterns\Factory\SimpleFactory\Pizza.java
O método fábrica
O método fábrica
•
Define uma interface para criação de um objeto, mas
deixa as subclasses definirem que classe instanciar
•
O pattern "Factory Method" permite a uma classe delegar
a instanciação às subclasses
Aplicações
•
Uma classe não pode antecipar a classe de objetos que
deve ser criada
•
Uma classe quer que suas subclasses especifiquem os
objetos que ela cria
•
Classes delegam responsabilidades para uma dentre
várias subclasses auxiliares, e deseja-se localizar o
conhecimento de qual subclasse auxiliar implementa a
delegação
O método fábrica
Conseqüências
•
Provê ganchos para as subclasses
•
Conecta hierarquias de classes paralelas quando há
delegação
O código fonte
Ver arquivo
Design Patterns\Factory\FactoryMethod\Pizza.java
Fábrica Abstrata
Fábrica Abstrata
•
Provê uma interface para a criação de famílias de objetos
relacionados ou dependentes sem especificar suas
classes concretas
Aplicações
•
Um sistema deve ser independente de como seus
elementos são criados, compostos e representados
•
Um sistema deve ser configurado para trabalhar com
uma única família dentre múltiplas famílias de produtos
•
Uma família de produtos relacionados é projetada para
ser usada em conjunto, e há a necessidade de reforçar
essa restrição
•
Se quer criar uma biblioteca de classes de produtos,
revelando apenas suas interfaces e não suas
implementações
Uma fábrica abstrata
Conseqüências
•
Isola as classes concretas
•
Facilita a troca de famílias de produtos
•
Prove consistência entre produtos
•
Facilita o suporte a novos tipos de produtos
O código fonte
Ver arquivo
Design Patterns\Factory\AbstractFactory\Pizza.java
Singleton
Singleton
•
Garante que uma classe tenha apenas uma instância, ou
um número controlado de instâncias, e provê um ponto
de acesso global a ela(s).
Aplicação
•
É usado quando:
•
deve haver exatamente uma única instância de uma
classe, e ela deve estar disponível a todos os clientes a
partir de um ponto de acesso bem definido
•
quando se deseja que a única instância possa ser
estendida por herança, e os clientes serem capazes de
utilizar essa instância estendida sem terem de modificar o
seu código
Estrutura
Conseqüências
•
Acesso controlado à instância única
•
Espaço de nomes reduzido
•
Permite refinamento de operações e representação via
especialização
•
Permite um número variável de instâncias
•
Maior flexibilidade do que em operações de classes
O código fonte
Ver arquivo Design Patterns\Singleton\Pizza.java
Strategy
Strategy
•
O padrão Strategy define uma família de algoritmos
intercambiáveis e encapsula cada um deles fazendo com
que eles possam ser permutáveis.
•
O padrão Strategy permite que os algoritmos variem
independentemente dos clientes que os utilizam
Aplicações
•
Usado quando muitas classes relacionadas diferem
apenas em alguns de seus comportamentos
•
O padrão Strategy provê uma maneira de configurar uma
classe com um entre vários comportamentos possíveis
Estrutura
Trocando o comportamento em tempo de
execução
O código fonte
Ver arquivos
Design Patterns\Strategy\ImplementacaoPobre\Teste.java
Design Patterns\Strategy\ImplementacaoMelhor\Teste.java
Design Patterns\Strategy\ComportamentoDinamico\Teste.java
Iterator
Iterator
•
Provê um modo de acessar seqüencialmente elementos
de um objeto agregado sem expor sua representação
básica
Aplicações
•
Serve para acessar o conteúdo de um objeto agregado
sem expor sua representação interna
•
Permite suportar múltiplas varreduras de objetos
agregados
•
Provê uma interface uniforme para varrer diferentes
estruturas agregadas de forma polimórfica
Estrutura
Conseqüências
•
Simplifica a interface do agregado
•
Mais de um caminho pode estar pendente em um
agregado
O código fonte
Ver arquivos
Design Patterns\Iterator\ImplementacaoPobre\Teste.java
Design Patterns\Iterator\ImplementacaoMelhor\Teste.java
Composite
Composite
•
O padrão a ser usado quando você tem coleções de
objetos com um relacionamento todo-parte e você quer
ser capaz de tratar estes objetos uniformemente
•
O padrão Composite fornece uma estrutura para
armazenar tanto objetos individuais como coleções
destes objetos
•
O padrão Composite permite aos clientes tratar objetos
individuais e coleções de objetos uniformemente
Composite
Exemplo
empresa
dptoA
Alberto
dptoB
Antonio
Brito
dptoC
Batista
dptoB1
Bento
Carlos
Bezerra
Cardoso
Composite
• Define uma hierarquia de classes que consiste de objetos
individuais (Leaf) e objetos compostos (Composite).
• Um elemento da árvore é qualquer objeto na estrutura do
Composite. Elementos podem ser objetos individuais ou
objetos compostos. Objetos compostos, por sua vez, podem
ser constituídos de objetos individuais e outros objetos
compostos, e assim por diante.
• Em qualquer ponto do código cliente em que se espera um
objeto individual, também pode ser usado um objeto
composto.
Composite
•
O cliente pode tratar estruturas compostas e objetos
individuais uniformemente.
•
Os clientes normalmente não sabem (e não devem se
preocupar) se eles estão tratando com um objeto
individual ou composto.
•
Permite a simplificação do código do cliente, porque evita
escrever funções que tenham que testar o tipo das
classes que definem a composição.
Composite
•
Torna-se mais fácil adicionar novos tipos de
componentes: basta que eles implementem a interface de
um elemento da árvore.
•
Novas definições das subclasses "Leaf" ou "Composite"
trabalham automaticamente com as estruturas existentes
e o código do cliente.
•
Os clientes não precisam ser modificados devido a
criação de novas classes que implementem a interface.
O código fonte
Ver arquivos
Design Patterns\Composite\Simples\Teste.java
Design Patterns\ Composite\Sofisticada2\Teste.java
Facade
Facade
•
Provê uma interface unificada para um conjunto de
interfaces em um subsistema.
•
Define uma interface de mais alto nível que torna mais
fácil o uso do subsistema.
Aplicações
•
Oferecer uma interface simples para um subsistema
complexo
•
Existem muitas dependências entre clientes e as classes
de implementação de uma abstração.
•
A introdução de um "Façade" irá desacoplar o subsistema dos
clientes dos outros subsistemas, promovendo assim, a
independência e portabilidade desses subsistemas.
Aplicações
•
Quando se deseja subsistemas em camadas.
•
Use um "Façade" para definir um ponto de entrada para cada
nível do subsistema. Se os subsistemas são dependentes, então
pode-se simplificar a dependência entre eles fazendo com que
eles se comuniquem uns com os outros unicamente através dos
seus "Façades".
A Biblioteca: Uma implementação pobre
A Biblioteca: Uma implementação pobre
A Biblioteca: Uma implementação melhor
A Biblioteca: Uma implementação melhor
Conseqüências
•
Isola os clientes dos componentes do subsistema,
reduzindo desse modo o número de objetos com que o
cliente interage, fazendo com que o subsistema seja
muito mais fácil de se usar.
•
Ajuda a estruturar o sistema em camadas.
•
Promove um acoplamento fraco entre o subsistema e
seus clientes.
•
Geralmente os componentes de um subsistema são fortemente
acoplados. Um baixo acoplamento entre subsistemas permite que
se varie os componentes de um subsistema sem afetar seus
clientes.
O Código Fonte
Ver arquivos
Design Patterns\Facade\ImplementacaoPobre\Usuario.java
Design Patterns\ Facade\ImplementacaoMelhor\Usuario.java
Observer
Observer
•
O padrão Observer define uma relação um para muitos
entre objetos
•
O objeto Observado atualiza os Observadores utilizando
uma interface comum.
•
O objeto Observado e os Observadores são fracamente
acoplados na medida em que o objeto Observado não
conhece os Observadores e nada sabe sobre eles a não
ser que eles implementam a interface Observador.
Observer
•
O objeto observado pode enviar o seu estado aos
observadores (push) ou disponibilizar métodos de acesso
para seus dados (pull). Pull é geralmente considerado
mais correto.
•
Seu programa não deve confiar em que as notificações
aos observadores ocorram numa dada ordem.
•
Java tem várias implementações do padrão Observer,
incluindo o Observer genérico java.util.Observer
Um exemplo
Uma implementação ruim
Codificando para uma implementação concreta, não temos como
acrescentar novas apresentações sem modificar o programa
Ainda uma implementação ruim: Usando um
Objeto de Transferência de Dados
As interfaces Observador e Observavel
Usando as interfaces Java Observer e
Observable
Usando as interfaces Java Observer e
Observable com métodos pull
Download

DesignPatterns