Escolar Documentos
Profissional Documentos
Cultura Documentos
J930
Padrões
de
Projeto
3 Padrões de
Responsabilidade
Introdução: Responsabilidades
• A decomposição em classes e objetos distribui
responsabilidades em cada objeto e método do sistema
• Responsabilidades podem ser controladas em Java
usando encapsulamento e controle de acesso, definindo
• interfaces globais estáticas (public static)
• interfaces para clientes de objetos (public)
• interfaces para clientes de classes (protected)
• interfaces internas ao desenvolvimento (package-private)
• dados e operações internas à classe (private)
• Design patterns utilizam esses recursos para ir além e
oferecer controle mais preciso
• Controle distribuído em objetos específicos
• Controle centralizado em um um único objeto
• Notificação e intermediação de requisições
2
5
Singleton
Problema
Problema (2)
Estrutura de Singleton
Singleton em Java
Prós e contras
• Vantagens
• Acesso central e extensível a recursos e objetos
• Pode ter subclasses* (o que seria impossível se fosse
apenas usada uma classe com métodos estáticos)
• Desvantagens
• Qualidade da implementação depende da linguagem
• Difícil de testar (simulações dependem de instância extra)
• Uso (abuso) como substituto para variáveis globais
• Criação "preguiçosa" é complicada em ambiente
multithreaded
• Difícil ou impossível de implementar em ambiente
distribuído (é preciso garantir que cópias serializadas
refiram-se ao mesmo objeto)
* Mas é complicado: requer controle em todas as subclasses para garantir instância única (pelo menos um construtor
precisa ser acessível às subclasses em Java) - use encapsulamento de pacote. 9
Resumo
10
Exercícios
• 5.1 Transforme a Fachada que você criou no capítulo sobre
Façade em um Singleton
• 5.2 Escreva uma classe executável (com main) que obtenha
três referências do objeto que você escreveu no exercício
anterior e verifique que realmente se tratam da mesma
referência.
• 5.3 [Challenge 8.4] Para cada classe abaixo, diga se aparenta
ser um Singleton e por que.
java.lang.System
java.lang.Math
+out:PrintStream
-Math()
+random (seed:double):double
PrintStream
PrinterManager PrintSpooler
11
6
Observer
Observador 1 Observador 2
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
13
Problema (2)
14
dadosObservados =
return dadosDoSujeito ; concreto .getDados ();
15
Seqüência de Observer
cliente a:ObservadorConcreto :SujeitoConcreto
cadastrar( this)
«create»
b:ObservadorConcreto
cadastrar(b)
notificar()
atualizar()
atualizar()
getDados ()
getDados ()
16
Prós e contras
• Vantagens
• Tanto observadores quando sujeitos observados podem ser
reutilizados e ter sua interface e implementação alteradas
sem afetar o sistema
• O acoplamento forte implicado pelo relacionamento
bidirecional é reduzido com o uso de interfaces e classes
abstratas
• Desvantagens
• O abuso pode causar sério impacto na performance.
Sistemas onde todos notificam todos a cada mudança
ficam inundados de requisições ("tempestade de eventos")
18
Model-View-Controller
• O padrão de arquitetura MVC é uma combinação de
padrões centrada no padrão Observer
• Consiste de três participantes
• Model: representa os dados da aplicação e regras de negócio
associadas com os dados. Notifica o View sobre alterações.
• View: é um Observer para o Model. Notifica o Controller
sobre eventos iniciados pelo usuário e lê dados do Model.
• Controller: é um Observer para o View. Encapsula lógica de
controle que afeta o Model e seleciona View.
« recupera estado »
« altera estado »
Model
« notifica »
20
:Cliente
«create»
:Model
Model()
«create»
:View
View(model)
addListener(this)
«create»
:Controller
Controller(model, view)
addListener(this)
21
Seqüência de operação
Usuário aperta
botão "Ação"
notificar()
processar()
setEstado(s)
notificar()
processar()
atualizar()
getEstado()
22
Exercícios
23
7
Mediator
24
Problema
Colaborador 1 Colaborador 2
Colaborador 3
25
Solução
•Introduzir um mediador
•Objetos podem se comunicar sem se conhecer
Colaborador 3
26
Colaborador
Mediador
mediador:Mediador
operacao Mediada()
chamarOperacao ()
ColaboradorUm
operacao Um()
MediadorConcreto
um:SujeitoUm
dois:SujeitoDois ColaboradorDois
operacao Mediada() operacao Dois()
...
um.operacaoUm ()
...
dois.operacaoDois ()
...
27
Descrição da solução
Mediator em Java
public interface Mediator {
public abstract class Colleague {
public void chaseOperation();
private Mediator mediator;
public void escapeOperation();
}
public void setMediator(Mediator m) {
mediator = m;
public class ConcreteMediator }
implements Mediator {
}
Colleague felix = new Gato();
Colleague mickey = new Rato();
public class Rato extends Colleague {
public ConcreteMediator() {
felix.setMediator(this); public void escapeCat() {
mickey.setMediator(this); mediator.escapeOperation();
} }
public void chaseOperation() {
... //if certa condição ... }
mickey.escapeCat();
...
} public class Cat extends Colleague {
public void escapeOperation() {
... //if certa condição ... public void chaseMouse() {
felix.chaseMouse(); mediator.chaseOperation();
... }
}
} }
29
Prós e contras
• Vantagens
• Desacoplamento entre os diversos participantes da rede
de comunicação: participantes não se conhecem.
• Eliminação de relacionamentos muitos para muitos (são
todos substituídos por relacionamentos um para muitos)
• A política de comunicações está centralizada no mediador
e pode ser alterada sem mexer nos colaboradores.
• Desvantagens
• A centralização pode ser uma fonte de gargalos de
performance e de risco para o sistema em caso de falha
30
Exercícios
31
8
Proxy
32
Problema
• Sistema quer utilizar objeto real...
pergunta("Vou a guerra?")
Creso Deus Apolo
33
«interface»
Cliente Sujeito
proxy:Sujeito = new Intermediario () operacao ()
executar () ...
proxy.operacao ()
Intermediario
SujeitoReal
real.SujeitoReal
operacao ()
Estrutura
operacao ()
...
...
de Proxy real.operacao ()
Proxy em Java
public class Creso {
...
Sujeito apolo = Fabrica.getSujeito();
apolo.operacao();
...
} inaccessível
pelo cliente
public class SujeitoReal implements Sujeito {
public Object operacao() {
return coisaUtil;
}
}
Quando usar?
• A aplicação mais comum é em objetos distribuídos
• Exemplo: RMI (e EJB)
• O Stub é proxy do cliente para o objeto remoto
• O Skeleton é parte do proxy: cliente remoto chamado pelo Stub
RemoteInterface
toUpper (String):String
Cliente
operacao ()
ObjetoRemoto
toUpper (String):String
stub.toUpper("a ")
Prós e contras
• Vantagens
• Transparência: mesma sintaxe usada na comunicação
entre o cliente e sujeito real é usada no proxy
• Permite o tratamento inteligente dos dados no cliente
• Permite maior eficiência com caching no cliente
• Desvantagens
• Possível impacto na performance
• Transparência nem sempre é 100% (fatores externos
como queda da rede podem tornar o proxy inoperante ou
desatualizado)
37
9
Chain of
Responsibility
"Evita acoplar o remetente de uma requisição ao seu
destinatário ao dar a mais de um objeto a chance de servir
a requisição. Compõe os objetos em cascata e passa a
requisição pela corrente até que um objeto a sirva." [GoF]
39
1 10 Problema
5
• Permitir que vários objetos possam
50
servir a uma requisição ou repassá-la
• Permitir divisão de responsabilidades
de forma transparente
receber() R$ 1,00
receber() R$ 0,50
Um objeto pode ser uma folha Total
ou uma composição de outros receber() R$ 0,10
objetos
receber() R$ 0,05
40
:Processador
:Processador
ProcessadorConcretoUm
sucessor:Processador
processarRequisicao () :Processador
ProcessadorConcretoDois
sucessor:Processador
processarRequisicao ()
...
sucessor.processarRequisicao () ProcessadorConcretoN
processarRequisicao ()
41
42
Exercícios
10
Flyweight
45
Problema
Pool de objetos
imutáveis
compartilhados
46
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
47
Prós e Contras
• Quando usar Flyweight
• Quando o tamanho do conjunto de objetos for
significativamente menor que a quantidade de vezes em
que eles são usados na aplicação
• Quando objetos podem ser usados em diferentes
contextos ao mesmo tempo (agindo sempre como um
objeto indepentente)
• Quando não usar
• Quando o estado dos objetos não for imutável (é preciso
passar o estado mutável como parâmetro e isto pode ser
impraticável se o estado consistir de vários objetos)
• Quando for necessário elaborar um algoritmo ou algo
complicado para separar objetos mutáveis de imutáveis
48
Exercícios
Testes
51
Fontes
52
www.argonavis.com.br