O documento discute padrões de projeto de software, abordando especificamente os padrões Adapter, Proxy e Composite. O Adapter permite que classes com interfaces incompatíveis trabalhem juntas, o Proxy controla o acesso a um objeto e o Composite trata objetos compostos e individuais de forma uniforme.
Padrões de projeto - Adapter, Proxy, Composite e Bridge
1. UNIVERSIDADE VILA VELHA
LORRAN PEGORETTI, LUIZ MARCON
TRABALHO REALIZADO PARA AVALIAÇÃO NA DISCIPLINA DE ENGENHARIA DE SOFTWARE II, DO
CURSO DE CIÊNCIA DA COMPUTAÇÃO, TURNO MATUTINO, DA UNIVERSIDADE DE VILA VELHA
(UVV), MINISTRADA PELO PROFESSOR CRISTIANO BIANCARDI.
2013
Padrões de Projeto
1
2. Tópicos abordados
Padrão de Projeto
Adapter
Proxy
Composite
Bridge
Conclusões
Referências
2
4. Padrão de Projeto
Um padrão é um conjunto de informações instrutivas que possui um
nome e que capta a estrutura essencial e o raciocínio de uma família
de soluções comprovadamente bem sucedidas para um problema
repetido que ocorre sob um determinado contexto e um conjunto de
repercussões
Um Padrão de Projeto de Software (Design Pattern) descreve uma
solução para um problema que ocorre com frequência durante o
desenvolvimento de software, podendo ser considerado como um par
“problema/solução”
Um Padrão de Projeto de Software não é um código final, é uma
descrição ou modelo de como resolver o problema do qual trata, que
pode ser usada em muitas situações diferentes.
4
5. Padrão de Projeto
Um padrão de projeto define
Nome
Todo padrão deve ter um nome significativo. Pode ser uma única palavra ou
frase curta que se refira ao padrão e ao conhecimento ou estrutura descritos
por ele. Se o padrão possuir mais do que um nome comumente usado ou
reconhecível na literatura, subseções “Aliases” ou “Also know as” devem ser
criadas
Problema
Estabelece o problema a ser resolvido pelo padrão, descreve a intenção e
objetivos do padrão perante o contexto e forças específicas
Solução
Relacionamentos estáticos e regras dinâmicas descrevendo como obter o
resultado desejado. Equivale a dar instruções que descrevem como o problema
é resolvido, podendo para isso utilizar texto, diagramas e figuras
5
6. Padrão de Projeto
Um padrão de projeto define
Contexto (Quando aplicar a solução)
Pré-condições dentro das quais o problema e sua solução costumam ocorrer e
para as quais a solução é desejável, o que reflete a aplicabilidade do padrão.
Pode também ser considerado como a configuração inicial do sistema antes da
aplicação do padrão
Resultado
O estado ou configuração do sistema após a aplicação do padrão, ou seja, as
“consequências” (tanto boas quanto ruins). Descreve as pós-condições e efeitos
colaterais do padrão
6
7. Padrão de Projeto
Visam facilitar a reutilização de soluções de desenho, isto é, soluções
na fase de projeto do software
Estabelecem um vocabulário comum de desenho, facilitando
comunicação, documentação e aprendizado dos sistemas
de software
7
8. Padrão de Projeto
Classificação
Quanto ao Escopo
Classes
Objetos
Quanto ao seu propósito
Criacional
Comportamental
Estrutural
Diz respeito a composição de objetos e classes. Exemplos:
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
8
10. Adapter
A intenção do Padrão Adapter é converter a interface de
uma classe para uma outra que os clientes esperam. O
Adapter permite que classes com interfaces incompatíveis
passem a trabalhar em conjunto
Basicamente, isso quer dizer que precisamos de uma
maneira de criar uma nova interface para um objeto que
funciona, mas que possui uma interface “errada”
10
11. Adapter
O padrão Adapter é muito utilizado quando precisamos
encaixar uma nova biblioteca de classes, adquirida de um
fornecedor, em um sistema de software já existente, porém
essas bibliotecas de classe do novo fornecedor são diferentes
das bibliotecas de classes do fornecedor antigo
A definição oficial do padrão Adapter: “O Padrão Adapter
converte uma interface de uma classe para outra interface que
o cliente espera encontrar. O Adaptador permite que classes
com interfaces incompatíveis trabalhem juntas”
O adaptador converte UMA interface para
outra, porém, também poderíamos ter um caso em que
precisaríamos adaptar mais de uma classe, nesse caso entra em
cena outro padrão de projeto, o Facade
11
12. Adapter
Diagrama de classe do Padrão Adapter
Fonte: http://www.devmedia.com.br/padrao-de-projeto-adapter-em-java/26467
12
15. Adapter
Comparação Adapter e Facade
Facade Adapter Comentário
As classe já existem? Sim Sim Já tenho classes em ambos
Existe uma interface que
devemos projetar?
Não Sim No facade, eu não preciso projetar uma interface como
no Adapter.
Um objeto precisa ter
comportamento
polimórfico?
Não Provável Não estou interessado no comportamento polimórfico
no Facade, enquanto que em Adapter provavelmente
estou.
É necessário que seja
uma interface simples?
Sim Não No caso do padrão Facade, a motivação é simplificar a
interface. Com o Adapter, eu estou tentando projetar
uma interface existente e não posso simplificar as
coisas, mesmo que seja possível simplificá-la.
Tabela 1 - Comparação padrão Facade com padrão Adapter.
15
17. Proxy
O objetivo principal é encapsular um objeto através de um outro
objeto que possui a mesma interface, de forma que o segundo
objeto, conhecido como “Proxy”, controla o acesso ao
primeiro, que é o objeto real.
17
18. Proxy - Vantagens
Permite deixar transparente o local (endereço) do objeto real. O
cliente não precisa conhecer se o objeto é remoto ou não, este
tipo de proxy é conhecido como Remote Proxy.
Útil para realizar otimizações, como cache de objetos. Também
pode ser implementado rotinas de logs e controle de acesso
(segurança). Este tipo de proxy é conhecido como Virtual Proxy
18
20. Proxy – Exemplo de uso
O framework Hibernate também utiliza o pattern Proxy, por
exemplo ao fazer o “lazy-loading”, técnica utilizado para acessar o
banco de dados apenas quando for necessário. Muitas vezes
quando trabalhamos com o Hibernate, e uma busca é
realizada, por exemplo usando o método “session.load(id)”, um
Proxy para o objeto real é retornado. Neste caso o objeto ainda
não está completamente preenchido, pois nenhum SQL foi
realizado até este momento. Apenas quando uma propriedade
deste objeto (métodos getX) ou um relacionamento, como por
exemplo “empresa.getFuncionarios()” forem chamados, a consulta
no banco será realizada. Tudo isto de forma transparente para o
cliente.
20
22. Composite
A intenção do Composite é compor objetos em estruturas de
árvore para representar hierarquias parte-todo
O Composite permite aos clientes tratarem de maneira
uniforme objetos individuais e objetos compostos
Em certas estruturas necessitamos por muitas vezes de
métodos e funções que já estão especificadas em um
determinado objeto, sendo necessário apenas a ligação
entre os dois para assim poder ser reutilizado o código
Tratar composições e unidades uniformemente
22
23. Composite
Exemplo de aplicação
Aplicações gráficas, tais como editores de desenho
permitem aos usuários construir diagramas complexos a
partir de componentes simples
O usuário pode agrupar componentes para formar
componentes ainda maiores, os quais, por sua
vez, podem ser agrupados para formar componentes
ainda maiores
Uma implementação simples poderia definir classes
para primitivas gráficas, como Texto e Linhas, além de
outras classes que funcionam como recipientes
(conteiners) para estas primitivas
23
24. Composite
Exemplo de aplicação
Gráfico
Linha Retângulo Texto
Container
Diagrama de classe Composite
24
25. Composite
Exemplo de aplicação
Há um problema com esta abordagem
O código que usa estas classes deve tratar objetos primitivos
e objetos recipientes de modo diferente, mesmo se na
maior parte do tempo o usuário os trate de forma idêntica
O padrão Composite descreve como usar a
composição de maneira recursiva tal que os clientes
não tenham que fazer esta distinção
25
26. Composite
Exemplo de aplicação
Diagrama de classe Composite
Linha
Desenhar()
Retangulo Texto Foto
Desenhar()
Add(g : Grafico)
Remover(g : Grafico)
GetFilho(c : int)
Grafico
Desenhar()
graficos
paraTodos g em graficos
g.Desenhar()
add g a lista de
graficos
Cliente
Desenhar() Desenhar()
26
32. Composite
Estrutura geral do padrão Composite
Participantes
Componente
Declara a interface para objetos na composição
Implementa comportamento default para interface comum a todas as
classes, como apropriado
Declara uma interface para acessar ou gerenciar seus componentes filhos
Folha
Representa objetos folhas na composição
Uma folha não tem filhos
Define comportamento para objetos primitivos na composição
32
33. Composite
Estrutura geral do padrão Composite
Participantes
Composição
Define comportamento para Componentes que têm filhos
Armazena Componentes filhos
Implementa operações relacionadas com filhos na interface do
Componente
Cliente
Manipula objetos na composição através da interface Componente
33
34. Composite
Estrutura geral do padrão Composite
Consequências
Com o uso do padrão Composite podemos criar objetos com
uma grande complexidade e eles serem compostos por
outros objetos menores, além de deixar o código bem
estruturado e de fácil entendimento, sendo rápida a forma de
adicionar novos componentes, métodos e funções
34
36. Bridge
A intenção do Padrão de Projeto Bridge é
desacoplar uma abstração de sua
implementação, de forma que as duas possam
variar independentemente
De novo
A intenção do Padrão de projeto Bridge é
desacoplar uma abstração de sua implementação
de tal forma que a implementação possa ser
facilmente trocada
Como?
Encapsulando os detalhes de implementação em
um objeto que é um componente da abstração
36
37. Bridge - Exemplo
Considere a construção de um módulo para desenhar figuras
Considere que há duas classes externas de desenho a serem
utilizadas: DP1 e DP2
Primeira versão: “somente retângulos devem ser desenhados”
Retângulos são definidos com dois pares de pontos
Solução:
DP1 DP2
Usado para desenhar
retângulos
draw_a_line(x1, y1, x2, y2) drawline(x1, x2, y1, y2)
Usado para desenhar
círculos
draw_a_circle(x, y, r) drawcircle(x, y, r)
Tabela 2 – Comparação classes de desenho
37
39. Bridge - Exemplo
Suponha agora, o seguintes novos requisitos
“As classes externas agora desenham círculos.
Portanto, nosso módulo de desenho deve também
ter a possibilidade de desenhar círculos”
“Além disso, o cliente do nosso módulo de desenho
não precisa saber a diferença entre um retângulo e
um círculo.”
Solução
Criamos uma classe abstrata Shape, e fazemos com que
ela seja superclasse tanto de Rectangle quanto de Circle
O cliente agora se comunica com objetos Shape
Sendo assim, temos uma nova solução
39
41. Bridge - Exemplo
Infelizmente, esta abordagem traz
novos problemas. Observe a 3ª linha
do diagrama de classes
As classes da linha representam quatro
tipos específicos de Shapes
E se eu tiver um outro programa de
desenho?
Seis tipos diferentes de Shapes (duas
árvores de programas)
E se eu tiver um outro tipo de Shape, outra variação de conceito?
Terei nove tipos diferentes de Shapes (para os três programas de
desenho)
41
42. Bridge - Exemplo
A explosão de classes surge porque, nesta solução, a
abstração (os tipos de Shape) e a implementação (os
programas de desenho) estão fortemente acoplados.
Cada tipo de figura (abstração) deve saber que tipo
de módulo externo (implementação) ele deve utilizar
Precisamos de um modo de desacoplar as variações na
abstração das variações na implementação, de tal forma
que o número de classes cresça somente linearmente
42
43. Bridge - Exemplo
Esta é exatamente a intenção do padrão Bridge
Desacoplar a abstração de sua implementação, de modo
que possam variar independentemente
Abstração 1
Abstração 2
Abstração 3
...
Implementação A
Implementação B
Implementação C
...
43
44. Bridge - Exemplo
Neste projeto, Shape usa Drawing para manifestar seu
comportamento, chegamos ao padrão Bridge
Diagrama de classes nova solução exemplo Padrão de Projeto Bridge, com padrão aplicado
44
46. Bridge – Exemplo aplicação
Exemplo Look and Feel – Java Swing
Objetos JFrame, JButton, etc. possuem um componente interno
que é construído com um “look and feel” particular
No entanto, clientes (programadores) somente precisam interagir
com JFrame, Jbutton, etc
WindowsLookAndFeel DefaultLookAndFeel
46
47. Bridge – Exemplo aplicação
Exemplo abstração driver específico do banco de dados
47
48. Bridge
Aplicabilidade
O padrão Bridge é útil quando se tem uma abstração que tem
diferentes implementações
Este padrão permite que a abstração e a sua implementação
variem independentemente
O projeto e a implementação são mais robustos e mais flexíveis às
mudanças futuras quando se usa o padrão
48
51. Referências
Padrões e Frameworks de Software - http://www2.icmc.usp.br/~rtvb/apostila.pdf
Padrão de Projeto Adapter em Java - http://www.devmedia.com.br/padrao-de-
projeto-adapter-em-java/26467
Padrões de projeto proxy - http://www2.lccv.ufal.br/Members/psycho/a-day-in-
life/padroes-de-projeto-proxy
Padrão de Projeto – Composite -
http://padroesdeprojetodesoftware.blogspot.com.br/2012/06/nome-e-classificacao-
do-padrao.html
Padrões de Projeto - http://www.cin.ufpe.br/~if718/transparencias/pdf/05-
padroesGoF.pdf
Pattern Proxy - http://www.devmedia.com.br/pattern-proxy/4066#ixzz2Tsfmdiih
Padrões de Projeto -
http://www.inf.ufsc.br/~bosco/extensao/NovosTalentos2012/D:/additional/addnlApps
/jhtp6_appM_design_patterns.pdf
Módulo III Padrões GOF: Bridge – (Professores: Eduardo Bezerra, Isamel H F Santos –
PUC-RIO) http://www.tecgraf.puc-rio.br/~ismael/Cursos/XJavaPadroes/aulas/3-
PadroesGOF/JavaPadroes_3-PadroesGOF-Bridge.pdf
51