Design Patterns
Design Patterns
Design Patterns
de
Design
com aplicaes em Java
2
O que um padro?
5
Responsabilidades e
Diagramas de Interao
Diagramas de interao mostram escolhas ao atribuir
responsabilidades a objetos
No diagrama de
colaborao ao lado
objetos Order tm
a responsabilidade
de se prepararem:
mtodo prepare()
O cumprimento dessa
responsabilidade requer
colaborao com
objetos Order Line e
Stock Item
Fonte: [4] Craig Larman, Applying UML and Patterns, 2nd. Edition 6
Padres
7
Padres GRASP
Introduzidos por Craig Larman em seu livro Applying
UML and Patterns [4]
GRASP: General Responsibility and Assignment
Software Patterns
Os padres GRASP descrevem os princpios fundamentais da
atribuio de responsabilidades a objetos, expressas na
forma de padres
Esses padres exploram os princpios fundamentais de
sistemas OO
5 padres fundamentais
4 padres avanados
Se voc conhece os padres GRASP, pode dizer que
compreende o paradigma orientado a objetos
8
Padres clssicos ou padres GoF
O livro "Design Patterns (1994) de Erich Gamma,
John Vlissides, Ralph Jonhson e Richard Helm,
descreve 23 padres de design [2]
So solues genricas para os problemas mais comuns do
desenvolvimeto de software orientado a objetos
O livro tornou-se um clssico na literatura orientada a
objeto e continua atual
No so invenes. So documentao de solues obtidas
atravs da experincia. Foram coletados de experincias
de sucesso na indstria de software, principalmente de
projetos em C++ e SmallTalk
Os quatro autores, so conhecidos como "The Gang of
Four", ou GoF
9
Mais padres?
10
Por que aprender padres?
Aprender com a experincia dos outros
Identificar problemas comuns em engenharia de software e
utilizar solues testadas e bem documentadas
Utilizar solues que tm um nome: facilita a comunicao,
compreenso e documentao
Aprender a programar bem com orientao a objetos
Os 23 padres de projeto "clssicos" utilizam as melhores
prticas em OO para atingir os resultados desejados
Desenvolver software de melhor qualidade
Os padres utilizam eficientemente polimorfismo, herana,
modularidade, composio, abstrao para construir cdigo
reutilizvel, eficiente, de alta coeso e baixo acoplamento
11
Por que aprender padres?
Vocabulrio comum
Faz o sistema ficar menos complexo ao permitir que se
fale em um nvel mais alto de abstrao
Ajuda na documentao e na aprendizagem
Conhecendo os padres de projeto torna mais fcil a
compreenso de sistemas existentes
"As pessoas que esto aprendendo POO freqentemente
reclamam que os sistemas com os quais trabalham usam
herana de forma complexa e que difcil de seguir o fluxo
de controle. Geralmente a causa disto que eles no
entendem os padres do sistema" [GoF]
Aprender os padres ajudam um novato a agir mais como
um especialista
12
Elementos de um padro
Nome
Problema
Quando aplicar o padro, em que condies?
Soluo
Descrio abstrata de um problema e como usar os
elementos disponveis (classes e objetos) para solucion-lo
Conseqncias
Custos e benefcios de se aplicar o padro
Impacto na flexibilidade, extensibilidade, portabilidade e
eficincia do sistema
13
Padres GoF: Formas de classificao
H vrias formas de classificar os padres. Gamma et al
[2] os classifica de duas formas
Por propsito: (1) criao de classes e objetos, (2)
alterao da estrutura de um programa, (3) controle do
seu comportamento
Por escopo: classe ou objeto
Metsker [1] os classifica em 5 grupos, por inteno
(problema a ser solucionado): Padres GRASP focam
(1) oferecer uma interface, neste objetivo
(2) atribuir uma responsabilidade,
(3) realizar a construo de classes ou objetos
(4) controlar formas de operao
(5) implementar uma extenso para a aplicao
14
Classificao dos 23 padres segundo GoF*
Propsito
1. Criao 2. Estrutura 3. Comportamento
Escopo Classe Factory Method Class Adapter Interpreter
Template Method
Objeto Abstract Factory Object Adapter Chain of Responsibility
Builder Bridge Command
Prototype Composite Iterator
Singleton Decorator Mediator
Facade Memento
Flyweight Observer
Proxy State
Strategy
Visitor
* Padres "clssicos" selecionados e organizados por Gamma et al. "Design Patterns" [2]
15
Classificao dos padres GoF
segundo Metsker [1]
Inteno Padres
Fonte: [2] 17
Introduo: interfaces
18
Alm das interfaces
19
1
Adapter
"Objetivo: converter a interface de uma classe em outra
interface esperada pelos clientes. Adapter permite a
comunicao entre classes que no poderiam trabalhar
juntas devido incompatibilidade de suas interfaces." [GoF]
Problema e Soluo
Problema
Cliente
operacao() void operacao() {
metodoEsperado();
} Soluo
ClasseExistente Adaptador
metodoUtil() metodoEsperado()
void metodoEsperado() {
metodoUtil();
}
Adaptador
21
Duas formas de Adapter
implementa
Adaptador
operacao() metodoUtil()
Adaptador ClasseExistente ce
operacao() = new ClasseExistente ()
...
ce.metodoUtil()
27
2
Faade
28
Cliente precisa saber Problema
muitos detalhes do
subsistema para Cliente
utiliz-lo!
Subsistema
29
Estrutura de Faade
Cliente
Crie uma fachada!
Subsistema
30
Aplicao
f:Faade
Faade Exemplo
banco:BancoDeDados
operacao()
registrar()
comprar()
fecharCompra(id)
f.registrar("Z", 123);
f.comprar(223, 123);
f.comprar(342, 123); Cliente c =
f.fecharCompra(123); banco.selectCliente(id);
double valor =
c.getCarrinho.getTotal();
banco.processarPagamento(c, valor);
Carrinho
create():Carrinho
adicionar(Produto p)
getTotal():double
BancoDeDados
selectCliente(id)
selectProduto(id):Produto
Cliente processarPagamento()
create(nome,id):Cliente
adicionarCarrinho(Carrinho c)
getCarrinho():Carrinho InterfaceDeDados
Produto
create(nome, id,preco):Produto
getPreco():double
31
Faade em Java public class Facade {
BancoDeDados banco = Sistema.obterBanco();
public void registrar(String nome, int id) {
Cliente c = Cliente.create(nome, id);
class Aplicao { Carrinho c = Carrinho.create();
... c.adicionarCarrinho();
Facade f; }
// Obtem instancia f public void comprar(int prodID, int clienteID) {
f.registrar("Z", 123); Cliente c = banco.selectCliente(cliente ID);
f.comprar(223, 123); Produto p = banco.selectProduto(prodID) {
f.comprar(342, 123); c.getCarrinho().adicionar(p);
}
f.fecharCompra(123); public void fecharCompra(int clienteID) {
... Cliente c = banco.selectCliente(clienteID);
double valor = c.getCarrinho.getTotal();
} banco.processarPagamento(c, valor);
}
}
33
Nvel de acoplamento
Fachadas podem oferecer maior ou menor isolamento
entre aplicao cliente e objetos
Nvel ideal deve ser determinado pelo nvel de acoplamento
desejado entre os sistemas
A fachada mostrada como exemplo isola totalmente o
cliente dos objetos
Facade f; // Obtem instancia f
f.registrar("Z", 123);
35
3
Composite
Cliente
Rede
Rede
37
Tratar grupos e indivduos Soluo
diferentes atravs de uma
nica interface
Cliente
Todo mundo
* componente!
Componente
* Individuo
Individuo Grupo
38
Estrutura de Composite
:Composicao
Componente
Cliente
operacao() 1..*
filhos
Folha Composicao
operacao() operacao() for (int i=0; i<filhos.length; i++) {
add(Componente) filho = filhos[i];
remove(Componente) filho.operacao();
}
getFilho(int)
39
Composite em Java
import java.util.*;
public class MachineComposite extends MachineComponent {
protected List components = new ArrayList();
public void add(MachineComponent component) {
components.add(component);
}
public int getMachineCount() {
// Exerccio
} public abstract class MachineComponent {
} public abstract int getMachineCount();
public String getName() {
return name;
O que colocar no lugar }
public void setName(String name) {
indicado para implementar this.name = name;
corretamente esta classe? }
}
public abstract class Machine extends MachineComponent {
public int getMachineCount() {
// Exerccio
} Fonte: [2]
}
40
Quando usar?
Necessidade de um driver
Exemplo: implementaes especficas para tratar
objeto em diferentes meios persistentes
Publicao
getTitulo()
getAutor(id)
PublicaoImplXML PublicaoImplBD
getTitulo() getTitulo()
getAutor(id) getAutor(id)
44
Problema (II)
Livro Revista
getISBN() getArtigo()
45
imp.getDados(this)
Soluo: usar Bridge
Publicao
interface
imp:Implementador
Cliente Implementador
obterDados(tipo) getDados(tipo)
getTitulo()
getAutor(id)
PublicacaoImplBD
getDados(tipo)
Livro Revista
getISBN() getArtigo()
getTitulo() getTitulo()
getAutor() getAutor(id)
PublicacaoImplXML
getDados(tipo)
tipo.setTitulo("...");
tipo.setAutores(...);
tipo.setOutros(...);
46
Estrutura de Bridge
Abstrao interface
Cliente Implementador
imp:Implementador
implOperao()
operao()
ImplConcretaUm
RefinamentoDaAbstrao ImplConcretaDois
...
imp.implOperao()
48
Questes
49
Resumo: quando usar?
Adapter
Adaptar uma interface existente para um cliente
Bridge
Implementar um design que permita total
desacoplamento entre interface e implementao
Faade
Simplificar o uso de uma coleo de objetos
Composite
Tratar composies e unidades uniformemente
50
Distribuio de responsabilidades
Os padres a seguir esto principalmente associados a
atribuies especiais de responsabilidade
Singleton: centraliza a responsabilidade em uma nica
instncia de uma classe
Observer: desacopla um objeto do conhecimento de que
outros objetos dependem dele
Mediator: centraliza a responsabilidade em uma classe que
determina como outros objetos interagem
Proxy: assume a responsabilidade de outro objeto (intercepta)
Chain of Responsibility: permite que uma requisio passe por
uma corrente de objetos at encontrar um que a processe
Flyweight: centraliza a responsabilidade em objetos
compartilhados de alta granularidade (blocos de montagem)
51
5
Singleton
52
Problema
53
Estrutura de Singleton
55
Prs e contras
Vantagens
Acesso central e extensvel a recursos e objetos
Desvantagens
Qualidade da implementao depende da linguagem
Difcil de testar (simulaes dependem de instncia extra)
Uso (abuso) como substituto para variveis globais
Inicializao lazy "preguiosa" complicada em ambiente
multithreaded ( um anti-pattern veja a seguir)
Difcil ou impossvel de implementar em ambiente
distribudo ( preciso garantir que cpias serializadas
refiram-se ao mesmo objeto)
56
Double-checked lazy Singleton anti-pattern:
No use!
[5] [6]
59
6
Observer
x
a
60
b
30
c
10
Problema
y 50 30 20
z 80 10 10
c b a
registra-se
Observador 1 Observador 2
a b c
a = 50% x 60 30 10
b = 30% y 50 30 20
c = 20% z 80 10 10
1 c b a
Observador 1 Observador 2
a b c
a = 20% x 60 30 10
b = 60% y 20 60 20
c = 20% z 80 10 10
2 c b a
notifica
a = 20%
b = 60%
c = 20%
3
61
Problema (2)
62
for (int i = 0; i < observadores.length; i++) {
observador = observadores[i];
Estrutura de
}
observador.atualizar();
Observer
Sujeito
observadores:Observador[] interface
cadastrar(Observador) Observador
1..*
remover(Observador) atualizar()
notificar()
SujeitoConcreto ObservadorConcreto
-dadosDoSujeito concreto:SujeitoConcreto
dadosObservados
+setDados()
+getDados() atualizar()
dadosObservados =
return dadosDoSujeito; concreto.getDados();
63
Seqncia de Observer
cliente a:ObservadorConcreto :SujeitoConcreto
cadastrar(this)
create
b:ObservadorConcreto
cadastrar(b)
notificar()
atualizar()
atualizar()
getDados()
getDados()
64
public class ConcreteObserver
implements Observer { Observer em Java
public void update(Observable o) {
ObservableData data = (ObservableData) o;
data.getData();
}
} public class ObservableData
extends Observable {
private Object myData;
public class Observable {
public void setData(Object myData) {
List observers = new ArrayList();
this.myData = myData;
notify();
public void add(Observer o) {
}
observers.add(o);
} public Object getData() {
return myData();
public void remove(Observer o) {
}
observers.remove(o);
}
}
create
:Model
Model()
create
:View
View(model)
addListener(this)
create
:Controller
Controller(model, view)
addListener(this)
66
Seqncia de operao
Usurio aperta
boto "Ao"
notificar()
processar()
setEstado(s)
notificar()
processar()
atualizar()
getEstado()
67
Questes
68
7
Mediator
"Definir um objeto que encapsula como um conjunto de
objetos interagem. Mediator promove acoplamento fraco ao
manter objetos que no se referem um ao outro
explicitamente, permitindo variar sua interao
independentemente." [GoF]
69
Problema
Colaborador 1 Colaborador 2
Colaborador 3
70
Soluo
Introduzir um mediador
Objetos podem se comunicar sem se conhecer
Colaborador 3
71
Estrutura de Mediator mediador.operacaoMediada();
Colaborador
Mediador
mediador:Mediador
operacaoMediada()
chamarOperacao()
ColaboradorUm
operacaoUm()
MediadorConcreto
um:SujeitoUm
dois:SujeitoDois ColaboradorDois
operacaoMediada() operacaoDois()
...
um.operacaoUm()
...
dois.operacaoDois()
...
72
Descrio da soluo
74
8
Proxy
"Prover um substituto ou ponto atravs do qual um objeto
possa controlar o acesso a outro." [GoF]
75
Problema
Sistema quer utilizar objeto real...
pergunta("Vou a guerra?")
Creso Deus Apolo
76
interface
Cliente
Sujeito
proxy:Sujeito = new Intermediario() operacao()
executar() ...
proxy.operacao()
Intermediario
SujeitoReal
real.SujeitoReal
operacao()
Estrutura
operacao()
...
...
de Proxy real.operacao()
Cliente
operacao()
ObjetoRemoto
toUpper(String):String
stub.toUpper("a")
80
9
Chain of
Responsibility
"Evita acoplar o remetente de uma requisio ao seu
destinatrio ao dar a mais de um objeto a chance de servir
a requisio. Compe os objetos em cascata e passa a
requisio pela corrente at que um objeto a sirva." [GoF]
81
1 10 Problema
5 Permitir que vrios objetos possam
50
servir a uma requisio ou repass-la
Permitir diviso de responsabilidades
de forma transparente
receber() R$ 1,00
receber() R$ 0,50
Um objeto pode ser uma folha Total
ou uma composio de outros receber() R$ 0,10
objetos
receber() R$ 0,05
82
Estrutura de Chain of Responsibility
sucessor
interface
:Processador
:Processador
ProcessadorConcretoUm
sucessor:Processador
processarRequisicao() :Processador
ProcessadorConcretoDois
sucessor:Processador
processarRequisicao()
...
sucessor.processarRequisicao() ProcessadorConcretoN
processarRequisicao()
83
Chain of Responsibility em Java
public class cliente {
...
Processador p1 = ...
Object resultado = p1.processarRequisicao();
...
}
84
Estratgias de Chain Of Responsibility
86
10
Flyweight
"Usar compartilhamento para suportar grandes quantidades
de objetos refinados eficientemente." [GoF]
87
Problema
Pool de objetos
imutveis
compartilhados
88
Estrutura
if(flyweightPool.containsKey(id)) {
return (Flyweight)flyweightMap.get(id);
} else {
de Flyweight
Flyweight fly = new FlyweightConcreto( genKey() );
flyweightPool.put(fly.getKey(), fly);
return fly;
}
FlyweightFactory interface
flyweightPool Flyweight
operacao(estadoMutavel)
getFlyweight(id)
FlyweightConcreto FlyweightConcretoNaoCompartilhado
estadoImutavel estadoMutavel
operacao(estadoMutavel) operacao(estadoMutavel)
Cliente
89
Prs e Contras
Flyweight uma soluo para construo de
aplicaes usando objetos imutveis
Ideal para objetos que oferecem servios (guardados em
caches e em pools)
Ideal para objetos que podem ser usados para construir
outros objetos
Problemas
Possvel impacto na performance (se houver muitas
representaes diferentes, elas no podem ser alteradas, e
preciso criar muitos objetos)
90
Questes
91
Resumo: Quando usar?
Singleton
Quando apenas uma instncia for permitida
Observer
Quando houver necessidade de notificao automtica
Mediator
Para controlar a interao entre dois objetos independentes
Proxy
Quando for preciso um intermedirio para o objeto real
Chain of Responsibility
Quando uma requisio puder ou precisar ser tratada por
um ou mais entre vrios objetos
Flyweight
Quando for necessrio reutilizar objetos visando
performance (cuidado com o efeito oposto!)
92
Questes
93
Alm dos construtores
Construtores em Java definem maneiras padro de
construir objetos. Sobrecarga permite ampla flexibilidade
Alguns problemas em depender de construtores
Cliente pode no ter todos os dados necessrios para
instanciar um objeto
Cliente fica acoplado a uma implementao concreta (precisa
saber a classe concreta para usar new com o construtor)
Cliente de herana pode criar construtor que chama mtodos
que dependem de valores ainda no inicializados (vide
processo de construo)
Objeto complexo pode necessitar da criao de objetos
menores previamente, com certo controle difcil de
implementar com construtores
No h como limitar o nmero de instncias criadas
94
Alm dos construtores
96
Cliente
Cliente precisa de uma casa. Passa as
informaes necessrias para seu diretor Problema
Diretor Utilizando as informaes passadas pelo cliente, ordena a criao da
casa pelo construtor usando uma interface uniforme
ConstrutorDeCasas ConstrutorDePredios
97
Exemplo
Diretor 1..* Construtor
construir() construirParteUm()
construirParteDois()
while(objetos.hasNext()) {
Construtor c = (Construtor) objetos.next();
c.construirParteUm();
...
c.construirParteDois();
} ConstrutorDeCasas
-resultadoFinal
Cliente construirParteUm()
construirParteDois()
getCasa():Casa
ConstrutorDePredios
-resultadoFinal
construirParteUm()
construirParteDois()
getPredio():Predio
98
builders Exemplo: GoF
TextConverter
RTFReader builder convChar(char)
parseRTF() convFontChange(Font)
convParagraph()
TeXConverter TextWidgetConverter
convChar(char) convChar(char)
convFontChange(Font) convFontChange(Font)
convParagraph() convParagraph()
getTeXText() getTextWidget()
create
while (token = (Glyph)tokens.hasNext()){
switch token.type { create
CHAR: TeXText TextWidget
builder.convChar(token.Char)
FONT:
builder.convFontChange(token.Font)
PARA:
builder.convParagraph()
Client
}
}
99
Seqncia de Builder
cliente
create
:ConstrutorConcreto
create
:Diretor
construir()
construirParteUm()
construirParteDois()
construirParteTres()
getResultados()
100
Quando usar?
Builder permite que uma classe se preocupe com
apenas uma parte da construo de um objeto. til
em algoritmos de construo complexos
Use-o quando o algoritmo para criar um objeto complexo
precisar ser independente das partes que compem o
objeto e da forma como o objeto construdo
Builder tambm suporta substituio dos
construtores, permitindo que a mesma interface seja
usada para construir representaes diferentes dos
mesmos dados
Use quando o processo de construo precisar suportar
representaes diferentes do objeto que est sendo
construdo
101
Questes
102
12
Factory Method
103
O acesso a um objeto concreto ser Problema
atravs da interface conhecida ShapeFactory
Circle
draw()
Factory Method
getProduto():Produto
operacao()
CriadorConcretoA CriadorConcretoB
produto:ProdutoConcrA produto:ProdutoConcrB
Produto getProduto():Produto getProduto():Produto
metodo()
produto =
ProdutoConcretoA new ProdutoConcretoB()
metodo() return produto;
ProdutoConcretoB
metodo()
106
Estrutura de ShapeFactory
Factory Method getShape():Shape
CircleFactory RectangleFactory
shape:Circle shape:Rectangle
Shape getShape():Shape getShape():Shape
draw()
shape =
Circle new Rectangle()
draw() return shape;
Rectangle
draw()
107
13
Abstract Factory
108
Problema
Criar uma famlia de objetos relacionados sem
conhecer suas classes concretas
Cliente
109
Estrutura de Abstract Factory
abstrao
implA
ProdutoConcretoUm
return new operacaoUm()
implA.ProdutoConcretoUm(); FabricaConcretaA
ProdutoConcretoDois
criarProdutoUm()
operacaoDois()
criarProdutoDois()
implB
ProdutoConcretoUm
operacaoUm()
FabricaConcretaB
ProdutoConcretoDois
criarProdutoUm()
return new operacaoDois()
criarProdutoDois()
implB.ProdutoConcretoDois();
110
Questes
111
14
Prototype
112
Problema
Criar um objeto novo, mas aproveitar o estado previamente
existente em outro objeto
new setYYY()
addXXX()
clone()
113
Estrutura de Prototype
Cliente Prottipo
operacao() clonar()
ProttipoConcretoUm ProttipoConcretoUm
clonar() clonar()
114
Resumo
115
15
Memento
116
Problema
Antes Ao Undo!
No funcionou!
Preciso de mais
informao!
117
Soluo: Memento
119
Estrutura de Memento
Nunca opera sobre ou examina o
contedo de um memento
Fonte Memento
estado -estado
criarMemento() ~getEstado()
setMemento(Memento m) ~setEstado()
Package-private (friendly)
S a Fonte tem acesso!
120
Seqncia
:Zelador :Fonte
criarMemento() create
m:Memento
setEstado()
setMemento(m)
getEstado()
121
Exemplo genrico Memento em Java
package memento;
dois()
}
Classe x =
new ClasseConcretaDois()
x.concreto()
ClasseConcretaUm ClasseConcretaDois
um() um()
trs() trs()
dois() dois()
127
Soluo: Template Method
128
Template Method em Java
public abstract class Template {
protected abstract String link(String texto, String url);
protected String transform(String texto) { return texto; }
public final String templateMethod() {
String msg = "Endereo: " + link("Empresa", "http://www.empresa.com");
return transform(msg);
}
129
Exemplo no J2SDK
O mtodo Arrays.sort (java.util) um bom exemplo de
Template Method. Ele recebe como parmetro um objeto do
tipo Comparator que implementa um mtodo compare(a, b) e
utiliza-o para definir as regras de ordenao
public class MedeCoisas implements Comparator<Coisa> {
public int compare(Coisa c1, Coisa c2) {
if (c1.getID() > c2.getID()) return 1; Coisa
if (c1.getID() < c2.getID()) return -1; id: int
if (c1.getID() == c2.getID()) return 0;
}
}
...
Coisa coisas[] = new Coisa[10]; Mtodo retorna 1, 0 ou -1
coisas[0] = new Coisa("A"); para ordenar Coisas pelo ID
coisas[1] = new Coisa("B");
...
Arrays.sort(coisas, new MedeCoisas());
...
130
Questes
131
17
State
132
Problema
Desconectado :Objeto
operao
if (estado == desconectado) {
faaIsto();
} else if (estado == conectado) {
Conectado faaAquilo();
} else {
faa();
}
Transmitindo operao
estado.faa()
TCPConnection TCPState
open() state open()
close() close()
acknowldge() acknowldge()
state.open()
134
Estrutura de State
Contexto interface
Estado
estado:Estado
requisicao() processar()
estado.processar()
EstadoConcretoUm EstadoConcretoDois
...
processar() processar()
Contexto:
define a interface de interesse aos clientes
mantm uma instncia de um EstadoConcreto que define o estado atual
Estado
define uma interface para encapsular o comportamento associado com um
estado particular do contexto
EstadoConcreto
Implementa um comportamento associado ao estado do contexto
135
State em Java
public class GatoQuantico {
public final Estado VIVO = new EstadoVivo();
public final Estado MORTO = new EstadoMorto();
public final Estado QUANTICO = new EstadoQuantico();
137
Problema
Vrias estratgias, escolhidas de
acordo com opes ou condies
if (guerra && inflao > META) {
if (guerra && inflao > META) { plano = new Estrategia_C();
doPlanoB(); } else if (guerra && recesso) {
else if (guerra && recesso) { plano = new Estrategia_B();
doPlanoC(); } else {
} else { plano = new Estrategia_A();
doPlanejado(); }
}
plano.executar();
Idntico a state na
Estratgia
implementao. executar();
Diferente na inteno!
strat.executarAlgoritmo()
...
EstrategiaConcretaUm EstrategiaConcretaDois
...
executarAlgoritmo() executarAlgoritmo()
140
public class Guerra {
Estrategia acao; Strategy em Java
public void definirEstrategia() {
if (inimigo.exercito() > 10000) { public interface Estrategia {
acao = new AliancaVizinho(); public void atacar();
} else if (inimigo.isNuclear()) { public void concluir();
acao = new Diplomacia(); }
} else if (inimigo.hasNoChance()) {
acao = new AtacarSozinho(); public class AtacarSozinho
} implements Estrategia {
} public void atacar() {
plantarEvidenciasFalsas();
public void declararGuerra() { soltarBombas();
acao.atacar(); derrubarGoverno();
} }
public void encerrarGuerra() { public void concluir() {
acao.concluir(); estabelecerGovernoAmigo();
} }
} }
142
19
Command
143
Command
Problema execute(): Object
new NovoSocioCommand
edit EditarCommand
del RemoverCommand
get MostrarSocioCommand
all ListarTodosCommand
all
Cliente
Aplicao
Complexa Command c = getCommand("all");
service() {
...
Object result = c.execute();
...
}
144
Estrutura de Command
Executor Comando
cmd:Comando
executar()
servio()
cmd.executar()
...
ComandoConcretoUm ComandoConcretoDois
cria
Cliente estado estado ...
executar() executar()
receptor.ao()
Receptor
ao()
145
Command em Java
public interface Command { public interface NewCommand implements Command {
public Object execute(Object arg);
} public NewCommand(Database db) {
this.db = db;
}
public class Server {
private Database db = ...; public Object execute(Object arg) {
private HashMap cmds = new HashMap(); Data d = (Data)arg;
int id = d.getArg(0);
public Server() { String nome = d.getArg(1);
initCommands(); db.insert(new Member(id, nome));
} }
}
private void initCommands() {
cmds.put("new", new NewCommand(db));
cmds.put("del",
new DeleteCommand(db));
... public class DeleteCommand implements Command {
}
public DeleteCommand(Database db) {
public void service(String cmd, this.db = db;
Object data) { }
...
Command c = (Command)cmds.get(cmd); public Object execute(Object arg) {
... Data d = (Data)arg;
Object result = c.execute(data); int id = d.getArg(0);
... db.delete(id);
} }
} }
146
Questes
147
State, Strategy e Command
Diferentes intenes, diagramas e
implementaes similares (ou idnticas)
Como distinguir?
State representa um estado (substantivo) e
geralmente est menos accessvel (a mudana de
estado pode ser desencadeada por outro estado)
Strategy representa um comportamento (verbo)
e escolhida dentro da aplicao (a ao pode ser
desencadeada por ao do cliente ou estado)
Command representa uma ao escolhida e
iniciada por um cliente externo (usurio)
148
20
Interpreter
149
Problema
Se comandos esto representados como objetos, eles
podero fazer parte de algoritmos maiores
Vrios padres repetitivos podem surgir nesses algoritmos
Operaes como iterao ou condicionais podem ser
frequentes: represent-las como objetos Command
Soluo em OO: elaborar uma gramtica para
calcular expresses compostas por objetos
Interpreter uma extenso do padro Command (ou um
tipo de Command; ou uma micro-arquitetura construda
com base em Commands) em que toda uma lgica de
cdigo pode ser implementada com objetos
150
Exemplo [GoF]
RegularExpression
interpret()
LiteralExpression expr1
SequenceExpression
literal expr2
interpret() interpret()
alternative1
RepetitionExpression AlternationExpression alternative2
interpret() interpret()
151
Questes
152
Resumo: quando usar?
Template Method
Para compor um algoritmo feito por mtodos abstratos que
podem ser completados em subclasses
State
Para representar o estado de um objeto
Strategy
Para representar um algoritmo (comportamento)
Command
Para representar um comando (ao imperativa do cliente)
Interpreter
Para realizar composio com comandos e desenvolver uma
linguagem de programao usando objetos
153
Introduo: Extenso
Desejado
ClasseDerivada
ClasseConcretaUm interface
metodoUm() InterfaceDois
metodoDois() metodoCinco() Efeito Possvel
metodoQuatro()
metodoTres() em Java
ClasseDerivada
ClasseConcretaDois
deleg:ClasseConcretaUm
deleg metodoCinco()
metodoQuatro() metodoQuatro()
metodoCinco() Classes existentes
157
Requisio
Problema
Requisio
getResultado()
getResultado()
getX()
getResultado()
getY()
getZ()
getResultado()
getX()
158
Estrutura de Decorator
Componente
operao()
ComponenteConcreto Decorador
operao() operao() componente.operao();
super.operao();
comportamentoAdicional();
DecoradorConcretoUm DecoradorConcretoDois
estadoAdicional comportamentoAdicional()
operacao() operacao()
159
public abstract class DecoradorConcretoUm extends Decorador {
public DecoradorConcretoUm (Componente componente) { Decorator
}
super(componente);
Um componente
concreto
161
Concatenao
de
I/O streams
Concatenao do
decorador
// partindo do cano (componente concreto)
FileInputStream cano = new FileInputStream(tanque);
// decorador chf conectado no componente
InputStreamReader chf = new InputStreamReader(cano);
// pode-se ler um char a partir de chf (mas isto impede que
// o char chegue ao fim da linha: h um vazamento no cano!)
char letra = chf.read();
Uso de mtodo com
comportamento alterado
// decorador br conectado no decorador chf
BufferedReader br = new BufferedReader (chf);
// l linha de texto a de br Comportamento
String linha = br.readLine(); adicional
162
Questes
163
22
Iterator
164
Problema
Tipo de
referncia Coleo arbitrria de objetos
genrico Iterator (array, hashmap, lista, conjunto,
pilha, tabela, ...)
Object o =
iterator.next()
iterator.hasNext() ?
produz
Iterator Coleo
tem
165
Para que serve?
Iterators servem para acessar o contedo de um agregado
sem expor sua representao interna
Oferece uma interface uniforme para atravessar diferentes
estruturas agregadas
Iterators so implementados nas colees do Java. obtido
atravs do mtodo iterator() de Collection, que devolve uma
instncia de java.util.Iterator.
Interface java.util.Iterator:
package java.util;
public interface Iterator<E> {
boolean hasNext();
Object next();
void remove();
}
167
23
Visitor
168
Problema
Operaes Cliente Operao para suporte
fixas a extenses
Interface
Operaes
novas
plugveis
169
Para que serve?
Visitor permite
Plugar nova funcionalidade em objetos sem
precisar mexer na estrutura de herana
Agrupar e manter operaes relacionadas em uma
classe e aplic-las, quando conveniente, a outras
classes (evitar espalhamento e fragmentao de
interesses)
Implementar um Iterator para objetos no
relacionados atravs de herana
170
Antes Node
typeCheck()
generateCode()
Visitor: exemplo GoF
Depois
VariableRefNode AssignmentNode
typeCheck() typeCheck() NodeVisitor
generateCode() generateCode() visit(AssignmentNode)
visit(VariableRefNode)
TypeChkVisitor CodeGenVisitor
visit(AssignmentNode) visit(AssignmentNode)
visit(VariableRefNode) visit(VariableRefNode)
Depois
Node v.visit(this)
accept(NodeVisitor)
AssignmentNode VariableRefNode
accept(NodeVisitor v) v.visit(this) accept(NodeVisitor v)
171
Estrutura de Visitor interface
Visitante
visitarA(ElementoConcretoA)
visitarB(ElementoConcretoB)
Cliente
VisitanteConcretoUm VisitanteConcretoDois
visitarA(ElementoConcretoA) visitarA(ElementoConcretoA)
visitarB(ElementoConcretoB) visitarB(ElementoConcretoB)
Elemento
EstruturaDeObjetos
aceitar(Visitante)
ElementoConcretoA ElementoConcretoB
operacaoA() operacaoB()
aceitar(Visitante v) aceitar(Visitante v)
v.visitarA(this) v.visitarB(this)
172
Diagrama de seqncia
:EstruturaDeObjetos :ElementoConcretoA :ElementoConcretoB :VisitanteConcreto
aceitar(:Visitante)
visitarA(:ElementoConcretoA)
operacaoA()
aceitar(:Visitante)
visitarB(:ElementoConcretoB)
operacaoB()
173
Refatoramento para Visitor em Java: Antes
public interface Documento_1 { public class Texto_1
public void gerarTexto(); implements Documento_1 {
public void gerarHTML(); public void gerarTexto() {...}
public boolean validar(); public void gerarHTML() {...}
} public boolean validar() {...}
...
}
talvez o mais complexo dos
padres GoF public class Planilha_1
implements Documento_1 {
public void gerarTexto() {...}
public class Cliente { public void gerarHTML() {...}
public static void main(String[] args) { public boolean validar() {...}
Documento_1 doc = new Texto_1(); ...
Documento_1 doc2 = new Grafico_1(); }
Documento_1 doc3 = new Planilha_1();
doc.gerarTexto(); public class Grafico_1
doc.gerarHTML(); implements Documento_1 {
if (doc.validar()) public void gerarTexto() {
System.out.println(doc + " valido!"); System.out.println("Nao impl.");
doc2.gerarTexto(); }
doc2.gerarHTML(); public void gerarHTML() {
if (doc2.validar()) System.out.println("HTML gerado");
System.out.println(doc2 + " valido!"); }
doc3.gerarTexto(); public boolean validar() {
doc3.gerarHTML(); return true;
if (doc3.validar()) }
System.out.println(doc3 + " valido!"); public String toString() {
return "Grafico";
} }
} } 174
Visitor em Java (Depois)
public interface Visitante {
public Object visitar(Planilha p);
public Object visitar(Texto t);
public Object visitar(Grafico g);
}
178
Padres GRASP
Padres bsicos Padres GRASP refletem
Information Expert prticas mais pontuais da
Creator aplicao de tcnicas OO
High Cohesion
Low Coupling
Padres GoF exploram
Controller solues mais especficas
Padres avanados
Polymorphism
Pure Fabrication Padres GRASP ocorrem
Indirection na implementao de
vrios padres GoF
Protected Variations
179
Expert (especialista de informao)
Problema
Precisa-se de um princpio geral para atribuir
responsabilidades a objetos
Durante o design, quando so definidas interaes entre
objetos, fazemos escolhas sobre a atribuio de
responsabilidades a classes
Soluo
Atribuir uma responsabilidade ao especialista de informao:
classe que possui a informao necessria para cumpri-la
Comece a atribuio de responsabilidades ao declarar
claramente a responsabilidade
180
Expert
No sistema abaixo, uma classe precisa saber o total
geral de uma venda (Sale). Que classe deve ser a
responsvel?
183
Expert (4)
184
Creator
186
Creator
A nova responsabilidade conduzida por uma
operao em um diagrama de interaes
Um novo mtodo criado na classe de design para expressar
isto.
Problema
Como manter a complexidade sob controle?
Classes que fazem muitas tarefas no relacionadas
so mais difceis de entender, de manter e de
reusar, alm de serem mais vulnerveis mudana.
Soluo
Atribuir uma responsabilidade para que a coeso se
mantenha alta.
188
Coeso
Coeso [Funcional]
Uma medida de quo relacionadas ou focadas
esto as responsabilidades de um elemento.
Exemplo
Uma classe Co coesa se tem operaes
relacionadas ao Co (morder, correr, comer, latir)
e apenas ao Co (no ter por exemplo, validar,
imprimirCao, listarCaes)
Alta coeso promove design modular
189
High Cohesion
Que classe responsvel por criar um pagamento (Payment) e
associ-lo a uma venda (Sale)?
191
Low Coupling (baixo acoplamento)
Problema
Como suportar baixa dependncia, baixo impacto devido a
mudanas e reuso constante?
Soluo
Atribuir uma responsabilidade para que o acoplamento
mantenha-se fraco.
Acoplamento
uma medida de quanto um elemento est conectado a, ou
depende de outros elementos
Uma classe com acoplamento forte depende de muitas
outras classes: tais classes podem ser indesejveis
O acoplamento est associado coeso: maior coeso,
menor acoplamento e vice-versa.
192
Low Coupling
Payment
Register
Sale
193
Low Coupling
Qual das opes abaixo suporta o menor
acoplamento?
Opo 1
Opo 2
194
Controller
Problema
Quem deve ser o responsvel por lidar com um evento de
uma interface de entrada?
Soluo
Atribuir responsabilidades para receber ou lidar com um
evento do sistema para uma classe que representa todo o
sistema (controlador de fachada front controller), um
subsistema e um cenrio de caso de uso (controlador de
caso de uso ou de sesso).
Este padro semelhante (ou equivalente) a um
padro GoF. Qual?
195
Controller
196
Controller: problema
197
Controller: soluo
199
GRASP: Polymorphism
Problema:
Como lidar com alternativas baseadas no tipo? Como criar
componentes de software plugveis?
Deseja-se evitar variao condicional (if-then-else): pouco
extensvel.
Deseja-se substituir um componente por outro sem afetar o
cliente.
Soluo
No use lgica condicional para realizar alternativas
diferentes baseadas em tipo. Atribua responsabilidades ao
comportamento usando operaes polimrficas
Refatore!
200
GRASP: Pure Fabrication
Problema
Que objeto deve ter a responsabilidade, quando voc no
quer violar High Cohesion e Low Coupling, mas as solues
oferecidas por Expert no so adequadas?
Atribuir responsabilidades apenas para classes do domnio
conceitual pode levar a situaes de maior acoplamento e
menos coeso.
Soluo
Atribuir um conjunto altamente coesivo de responsabilidades
a uma classe artificial que no representa um conceito do
domnio do problema.
201
GRASP: Protected Variations
Problema
Como projetar objetos, subsistema e sistemas para que as
variaes ou instabilidades nesses elementos no tenha um
impacto indesejvel nos outros elementos?
Soluo
Identificar pontos de variao ou instabilidade potenciais.
Atribuir responsabilidades para criar uma interface estvel
em volta desses pontos.
Encapsulamento, interfaces, polimorfismo, indireo e
padres; mquinas virtuais e brokers so motivados por este
princpio
Evite enviar mensagens a objetos muito distantes.
202
GRASP: Indirection
Problema
Onde atribuir uma responsabilidade para evitar
acoplamento direto entre duas ou mais coisas? Como
desacoplar objetos para que seja possvel suportar baixo
acoplamento e manter elevado o potencial de reuso?
Soluo
Atribua a responsabilidade a um objeto intermedirio para
mediar as mensagens entre outros componentes ou servios
para que no sejam diretamente acoplados.
O objeto intermedirio cria uma camada de indireo entre
os dois componentes que no mais dependem um do outro:
agora ambos dependem da indireo.
Veja uma aplicao em: Dependency Injection
203
Injeo de dependncias
(inverso de controle)
inteface
ATest A InterB
205
Dependency Injection
Problema
Controle convencional: o prprio objeto cria ou
localiza suas dependncias: acoplamento!
ProgramadorJava
nome: String
certificacao:CertificacaoProgramadorJava
inscrever(): Certificado
JNDI
lookup(certificacaoSCEA)
new
CertificacaoProgramadorJava()
CertificacaoProgramadorJava CertificacaoArquitetoJ2EE
206
Exemplo: controle convencional
207
A dependncia
1:package faculdade;
2:
3:public class CertificacaoProgramadorJava {
4: public CertificacaoProgramadorJava() {}
5: public Certificado iniciarTeste()
throws NaoAprovadoException {
6: Certificado certificado = null;
7: // Realizar questoes
8:
9: return certificado;
10: }
11:}
208
Diminuindo o acoplamento
209
Soluo
ProgramadorJava
Certificacao
nome: String
certificacao:CertificacaoProgramadorJava
inscrever(): Certificado
setCertificacao(Certificacao);
programador.setCertificacao(this)
CertificacaoArquitetoJ2EE
programador.setCertificacao(certJ2EE)
CertificacaoProgramadorJava
210
Inverso de controle
public interface Programador {
public Object inscrever() throws NaoAprovadoException;
}
212
Tipos de interesse
Aspectos genricos
Caractersticas mover() e Figura
Poderiam ser usados em
desenhar() poderiam ser mover()
desenhar() outras aplicaes
reutilizadas em outros
objetos
mover()
validarCoords()
Retngulo Crculo Tringulo // cdigo p/ mover
logarAcao()
mover() mover() mover()
desenhar() desenhar() desenhar()
desenhar()
// cdigo p/ desenhar
logarAcao()
213
Problema: scattering e tangling
public class VeiculoPassageiro Scattering: acrescentar um
extends Veiculo { requerimento causa
public void abastecer() {
super.abastecer() + gasolina;
espalhamento do cdigo
Logger.log(nome() + em vrias classes
" abastecido com gasolina");
} ...
public class VeiculoCarga
}
extends Veiculo {
public void abastecer() {
super.abastecer() + diesel;
public class VeiculoAereo Logger.log(nome() +
extends Veiculo { " abastecido com diesel");
public void abastecer() { } ...
// cdigo }
Logger.log(nome() +
" abastecido com " + Tangling: cdigo para
x + " litros"); implementar o requerimento
// cdigo
} ... se mistura com lgica do
} cdigo existente 214
Incluso de nova funcionalidade
218
Soluo: MDSoC: HyperSpaces
Representao de unidades de software em mltiplas dimenses de
interesse
Eixos representam dimenses de interesse
Pontos nos eixos representam interesses
Unidades de software so representadas no espao
Hyperslices
Recurso
Encapsulam interesses
Cor Crculo Retangulo Triangulo
colorir() colorir() colorir() Hypermodule
Movimento Crculo Retangulo Triangulo Conjunto de hyperslices
mover() mover() mover() e relacionamentos de
Crculo Retangulo Triangulo integrao (informam
mover() mover() mover() como hyperslices se
Classe
relacionam entre si)
Circulo Retngulo Tringulo
Validao
Neste modelo, aspecto
apenas mais uma dimenso de
... interesse
Aspecto Outras dimenses
de interesse 219
Uso de aspectos
Antes Depois
220
Concluses
Neste minicurso, introduzimos diversos padres
usados em aplicaes OO
Padres clssicos GoF, que descrevem solues para
problemas comuns, elaborados
Padres GRASP, que descrevem aplicao de princpios OO
Padres e prticas emergentes como injeo de
dependncias (aplicao de uma prtica GRASP) e
aspectos (extenso do OO)
Aprenda a usar os padres clssicos e encurte o
tempo para ganhar tornar-se um programador
experiente!
Vrios outros padres existem e sero inventados
Alguns sobrevivero por muito tempo, outros no
Catalogue suas solues e crie seus prprios padres!
221
Fontes
222
Curso J930: Design Patterns
Verso 2.1
www.argonavis.com.br