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 arquivosDesign 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 arquivosDesign 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
Alberto Antonio
dptoA dptoB
Brito Batista dptoB1
Bento Bezerra
dptoC
Carlos Cardoso
empresa
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 arquivosDesign 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 arquivosDesign 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
Top Related