Buscar

3 - Padrões de Responsabilidade

Prévia do material em texto

10/04/2010
1
Padrões de Projeto
Carga Horária 67hs
Padrões de Responsabilidade
Prof. Giuseppe Anthony N. Lima
giuseppeanl@gmail.com
Instituto Federal de Educação Tecnológica da Paraíba
CST – Sistemas para Internet
1
Introdução
• Padrões de Responsabilidade
– Objetos são modelados para possuírem 
informações e métodos necessários 
• Colaborações devem se dar sem acoplamento
• O mundo OO distribui responsabilidades para objetos 
individuais: só operam sobre seus próprios dados
• Maior dependência entre classes causa baixa coesão
• Responsabilidade
– De fazer algo (não de ser algo!)
2
Introdução
• Coesão
– Baixo acoplamento entre classes de um software
– Clareza quanto as responsabilidades de uma 
classe
• Através de seus métodos ou serviços
• Baixa coesão causa dificuldades no projeto
– Entender
– Reusar
– Manter
3
Introdução
• Baixa coesão?
– Extrato bancário
public String extrato() {
//realiza a consulta dos lançamentos/movimentação bancária 
do cliente
//aplica bônus de pontuação referente a movimentação
//aplica multa em caso negativo
//realiza extrato na conta de investimento do cliente
} Você saberia que tudo isso era de responsabilidade 
desse método sem visualizar a implementação?
Se um cliente de extrato() contava com a 
funcionalidade de aplicar multa em caso negativo 
ou de atraso?
4
Introdução
• Proporcionando melhor coesão...
– Atribuindo responsabilidades específicas:
//solução com baixa coesão
public String extrato() {
//realiza a consulta dos lançamentos/movimentação bancária do 
cliente
//aplica bônus de pontuação referente a movimentação
//aplica multa em caso negativo
//realiza extrato na conta de investimento do cliente
}
//solução com a quebra de extrato() para proporcionar melhor coesão
public String aplicaBônus() { }
public String aplicaMulta(int tipoDeMulta) { }
public String extratoInvestimentos() { } 
Maior clareza?
Maior flexibilidade?
Maior reuso? 5
Singleton
• “Garantir uma determinada classe tenha uma 
única instância e que forneça um ponto de 
acesso global a ela”
6
10/04/2010
2
Singleton
• Motivação
– Como garantir que uma determinada classe seja 
instanciada uma única vez?
• Um único Banco de Dados
• Um único arquivo de log
• Um único Driver
7
Singleton
• Motivação
– Comportamento incorreto
– Uso excessivo de recursos
– Resultados inconsistentes
• Para tanto
– Como controlar o número de instâncias de 
classes?
– Como impedir o acesso aos construtores?
– Como armazenar as instâncias?
8
Singleton
• Utilizar classes estáticas diretamente
– Não há criação de instâncias
• Não há instanciação da entidade de interesse
• Ex: Math, System, etc.
– Conseqüências 
• Criadas no início da aplicação
• Podem não ser usadas
– Apenas por um período de tempo
– Permanecem na memória desde a “carga” da aplicação
9
Singleton
• Singleton 
– Garantir que uma determinada instância seja 
alocada apenas quando necessária e desalocada 
quando não for mais
– Ponto de acesso global
• Definir um construtor privado
• Declarar um objeto como estático controlar a 
construção via teste de condição
10
Singleton
Class Sigleton {
private static Singleton instancia;
private String nome;
private String idade;
private Singleton (String nome, String idade) {
this.nome = nome;
this.idade = idade;
}
public static Singleton getInstancia(String nome, String idade) {
if (instancia == null) {
instancia = new Singleton(nome, idade);
}
instancia;
}
11
Singleton
• Lazy Instantiation
– Instancia somente quando a classe será utilizada
• Eager Instatiation
– Instancia no momento da declaração da variável 
instance
• Sincronização 
– Se mais de um cliente numa aplicação 
multithreading estiver acessando getInstance() ao 
mesmo tempo?
• Mais de um objeto pode ser criado!
12
10/04/2010
3
Singleton
• Sincronização (cont)
public static synchronized Singleton getInstance() {
if (instance == null) {
return instance = new Singleton();
}
return instance;
}
13
Observer
• “Definir uma dependência um para muitos entre 
objetos de maneira que, quando um objeto muda 
de estado, todos os seus dependentes são 
notificados e atualizados automaticamente”
Observar a eminência 
de uma crise ou é ela 
que deve me avisar 
quando chegar?
14
Observer
• Necessidade de monitorar alterações do 
estado de um objeto
– Objetos interessados utilizam informações sobre o 
estado de um objeto de interesse
– Na alteração desse estado algo deverá ser feito
15
Observer
• Exemplo: Sensor de Segurança
– Uma aplicação de segurança se utiliza de um 
sensor
– O sensor possui um ponto de sensibilidade
• Se houver movimentação
• Se a intensidade da vibração for maior que o limite
– Caso isso ocorra
• Disparar alarme
• Disparar central de segurança
• Enviar mensagem para proprietário
16
• Representação do Esquema
Observer
Objeto de 
Interesse
Objeto 
Interessado
Objeto 
Interessado
Objeto 
Interessado
17
Observer
public class SensorSeguranca {
private Proprietario p = new Proprietario();
private ControleAlarme ca = new ControleAlarme();
private CentralSeguranca cs = new CentralSeguranca;
public void movimento() {
p.enviarMsg();
ca.disparar();
cs.chamarPolicia();
cs.chamarSeguranca();
}
} 
Forte acoplamento: observe como a classe 
se vincula a outros objetos somente para 
esses saberem quando algo ocorreu.
Se quiséssemos retirar ou colocar 
interessados em tempo de execução isso 
seria possível? :(
18
10/04/2010
4
Observer
• Nosso projeto mudou...
– Mudança 1
• Nosso SensorSegurança deve possuir agora um 
interessado chamado CentralPolicia, o que fazer?
– Referenciar como atributo de SensorSeguranca CentralPolicia
– Mudança 2
• Se quisesse que SensorSeguranca não possuisse como 
interessado CentralSegurança, o que fazer?
– Retirar a referência de SensorSegurança junto a CentralPolicia
19
Observer
• Nossa solução não está muito boa?
– O objeto de interesse sabe o que os interessados 
podem fazer 
• Conhecem sua interface
– Se quisermos adicionar/retirar objetos interessados 
devemos alterar em tempo de compilação
• Alterar o código da classe do objeto de interesse
• Forte acoplamento do objeto de interesse com interessados
– O tratamento da notificação é realizado no objeto de 
interesse e não no interessado
• Se objeto interessado possuir muitos objetos de interesse 
haveria muito código “misturado” para tratamento de uma 
notificação
20
Observer
• Solução: Aplicação do Padrão Observer
– Os objetos interessados passam a se registrar no objeto de 
interesse
– Definimos as operações no objeto de interesse que devem 
realizar notificação nos objetos de interessados
• Em geral operações que mudam o estado do objeto de interesse
– Objeto de interesse não deve saber quem são os 
interessados de fato
• Objetos interessados são reconhecidos apenas por sua interface
• Para não cair na tentação de implementar o código de tratamento 
da notificação
• Objeto de interesse deve notificar os interessados na ocorrência 
de alteração de estado
21
• Representação do Padrão
Observer
Objeto de Interesse = Subject
Se registra no objeto 
de interesse:
add(); remove()
Notifica os 
interessados: notify()
22
Observer
• Aplicando o padrão ao nosso aplicativo...
public class SensorSeguranca implements Observable {
private List<Observer> observers = new ArrayList<Observer>();
public void add(Observer observer) {
observers.add(observer);
}
public void remove(Observer observer) {
observers.remove(observer);
}
publicvoid notify() {
while (int 0; i < observers.size(); i++)
observers.get(i).update();
}
} 23
Observer
public class Proprietatio implements Observer {
public void update() {
enviarMsg();
}
}
public class CentralSeguranca implements Observer {
public void update() {
chamarPolicia();
chamarSeguranca();
}
}
public class ControleAlarme implements Observer {
public void update() { disparar(); }
}
24
10/04/2010
5
Observer
• Se quiséssemos coletar informações sobre o 
objeto de interesse no interessado?
– Passamos como parâmetro do método update um 
tipo Observable
• O método update(Observable obs) do interessado pode 
fazer um cast para acessar a interface e 
conseqüentemente os dados de um objeto de interesse
– Poderíamos criar uma classe de Event
• Event possui uma coleção de objetos dispostos em um 
mapa <chave, objeto> com uma interface que permita 
a manipulação dos dados do evento
• O método de Observer passa a ser update(Event e)
25
Observer
• Aplicabilidade
– É possível adicionar e remover observers
– Observable não faz distinção de observers
• A única coisa de o objeto de interesse sabe é que os interessados 
implementam uma interface
• Conseqüências
– Minimiza a responsabilidade de um objeto de interesse em relação a 
atualização de mudanças nos interessados
• O objeto de interesse apenas notifica!
• O tratamento de uma notificação é de responsabilidade dos interessados
– Permite desenvolver projetos em camadas
• Ex.: Elementos de interface ou representações gráficas (interessados) de um 
objeto e o próprio objeto da camada de negócio (objetos de interesse)
– Suporte a comunicação broadcast
• Todos os objetos interessados são notificados 
– Atualizações inesperadas
• Se o interessado não estiver preparado para tratar mudança de estado 
corretamente
26
Observer
• Observer em Java
27
Mediator
• Intenção
– Definir um objeto que encapsula a forma como 
um conjunto de objetos interage
• Esse objeto encapsula as regras de interação entre os 
objetos participantes
– Promover acoplamento fraco durante a 
comunicação
• Evitar que objetos se referenciem uns aos outros 
explicitamente
• O formato das interações (regras) podem variar 
independentemente
28
Mediator
• Projeto OO encoraja a distribuição de 
comportamentos entre vários objetos
– No entanto cada objeto possui um papel
• Reforçando boas práticas de projeto...
– Reduzir granularidade
– Favorecer composição
– Atribuir responsabilidades
Se isso não for observado 
haverá proliferação de 
interconexões entre objetos
29
Mediator
• Vamos entender melhor...
– Possuímos um grupo de objetos que operam 
colaborativamente
– Os comportamentos foram distribuídos entre 
esses objetos
• Promover a reusabilidade
– Essa distribuição tende a gerar muitas 
interconexões entre os objetos
• Acoplamento forte
• Aumento da glanularidade
30
10/04/2010
6
Mediator
• Exemplo
– Temos que construir uma interface gráfica com o 
usuário com os seguintes widgets...
Exemplo Fonte... Rótulo
Caixa de 
Seleção
BotõesBotões
Campo de 
texto
31
Mediator
• Interconectando...
– Ao selecionar tipo de fonte o rótulo deve ser 
atualizado e ainda:
• Ao digitar o nome da fonte no campo de texto a lista de 
seleção deverá atualizar sua seleção
• Ao escolher fonte na lista de seleção o campo de texto 
deverá conter o nome da fonte
– Ao selecionar negrito , sublinhado e itálico o 
rótulo deve ser atualizado
32
Mediator
• Interconexões demais?
Se quiséssemos 
aproveitar algum widget
teríamos que levar 
consigo essas relações!
33
Mediator
• Solução
– Vamos criar um objeto mediador que organiza a 
colaboração entre essas classes
34
Mediator
public interface Mediator {
public void entradaCampoTexto();
public void selecionaNegrito();
public void selecionaItalico();
public void selecionaSublinhar();
public void selecionaItemLista();
}
public class FontConfiguratorMediator implements Mediator {
//referências aos widgets ou seja aos objetos mediados
public void entradaCampoTexto() {
//procura por item na lista de seleção se existir seleciona e atualiza rótulo
//se não existir não faz nada
}
public void selecionaNegrito() { //atualiza rótulo como negrito }
public void selecionaItalico() { //atualiza rótulo como itálico } 
public void selecionaSublinhar() { //atualiza rótulo como sublinhado }
...
35
Mediator
//continuação de FontConfiguratorMediator...
public class FontConfiguratorMediator implements Mediator { 
public void selecionaItemLista() { //atualiza caixa de texto e rótulo }
}// mediador concreto termina aqui!
public interface Widget {
public abstract void changed();
} 
public class CampoDeTexto extends JTextField implements Widget { 
private Mediator med;
public void changed () {
med.entradaCampoTexto();
}
}
36
10/04/2010
7
Mediator
public class ListaDeSelecao extends JComboBox implements Widget {
private Mediator med; 
public void changed () {
med.selecionaItemLista();
}
}
public class BotaoItalico extends JButton implements Widget { 
private Mediator med;
public void changed () {
med.selecionaItalico();
}
}
public class BotaoNegrito extends implements Widget { 
private Mediator med;
public void changed () {
med.selecionaNegrito();
}
} 37
Mediator
public class BotaoSublinhado extends JButton implements Widget {
private Mediator med; 
public void changed () {
med.selecionaSublinhar();
}
}
38
Mediator
• Um único objeto Mediador é passado para 
seus colaboradores
– Nesse caso a classe mediadora também poderia 
ser um Singleton!
• A comunicação entre objetos parceiros pode 
ser feita via Observer quando possível
39
Mediator
• Conseqüências
– Limitação do uso de herança
• Se colaboradores estenderem de uma classe abstrata 
Colleague...
• Então se é fundamental para colaborador possuir herança, 
então Colleague poderá ser uma interface
– Desacoplamento entre parceiros
• Classes parceiras desconhecem sua dependência em relação 
as demais
– Simplificação do protocolo das classes
• Centralização do controle
– Abstração da maneira como objetos cooperam
• Se a forma de colaboração dos parceiros variar podemos 
implementar outro mediador para cada formato de 
colaboração
40
Mediator
• Para pensar...
– Projetar um chat através das classes Convidado e Sala
• A sala centraliza o envio e recebe mensagem e possuirá uma 
console, entrada de texto e lista de convidados na sala
• Quando uma mensagem for enviada à Sala deve ser repassada aos 
demais membros
• A Sala deve ser flexível para que qualquer Convidado entre ou saia 
quando quiser.
• Quando uma mensagem for enviada por um convidado a mesma 
deve aparecer em uma console e a ordem dos convidados deve 
mudar na lista
– Dá para utilizar Mediator?
• Quem media?
• Quais os colaboradores?
41
Proxy
• Intenção
– “Fornecer um substituto ou marcador de 
localização para que um objeto possa controlar o 
acesso a um outro”
– Proxy e Dicionário...
• Substituto, procurador, representante.
42
10/04/2010
8
Proxy
• Motivação
– Controlar e gerenciar o acesso a determinados 
objetos
• Controle: quem acessa o objeto?
• Gerência: como o acesso ao objeto é feito?
43
Proxy
• O que um Proxy faz?
– Um objeto atua como substituto/representante de 
um outro objeto que não pode ser acessado 
diretamente
– Alguns motivos para o objeto não poder ser 
acessado diretamente
• Objeto está localizado na memória de outro 
computador (objeto remoto)
• Controle de acesso (proteção do objeto real)
44
Proxy
• TiposComuns de Proxy
– Proxy Remoto
• Controla o acesso a um objeto remoto
– Proxy Virtual
• Controla o acesso a um objeto cuja criação é muito 
onerosa
– Proxy de Proteção
• Controla o acesso a um objeto real de maneira que o 
mesmo possa ser utilizado com restrições 
45
Proxy Remoto
• Proxy Remoto
– Representante local para um objeto remoto
• Recebe métodos do cliente e repassa para o 
responsável pelo serviço
• Transparente para o cliente
– Casos
• Aplicações Distribuídas Cliente-Servidor
• Web Services 
– Objetos participantes do serviço
• Integração entre sistemas distintos 
46
Pilha de Objetos no ServidorPilha de Objetos do Cliente
Proxy Remoto
Cliente
Proxy
Objeto 
Real 
Remoto
acesso
47
Proxy Remoto
• Características
– O objeto remoto real deve ser acessado de 
maneira transparente pelo cliente
• O cliente desconhece a implementação do acesso
– Um objeto real (remoto) e seu proxy 
representante (no cliente) devem possuir uma 
interface comum
• Define os métodos que um cliente pode chamar 
remotamente
• É a única coisa que o cliente sabe sobre o objeto real 
remoto!
48
10/04/2010
9
Proxy Remoto
• Representação arquitetural
Contém os métodos que 
poderão ser acessados 
remotamente
Cliente não tem 
conhecimento se é o objeto 
real ou seu substituto que 
está sendo utilizado: 
conhece apenas a interface 
49
Proxy Remoto
• Java RMI (Remote Method Invocation)
– Tecnologia baseada em sistemas distribuídos
– Permite a comunicação entre objetos que estão 
localizados em JVMs diferentes
– Semelhante às RPCs (Remote Procedure Call) em C
– Disponível no pacote java.rmi.*
– Serviços
• Serviços de busca (Lookup Service)
– Chamada através da localização de um objeto remoto
• Registro de serviços (Registry)
– Registro de um objeto remoto a partir da aplicação servidora 50
Proxy Remoto
• Estudo de caso
– Aplicação que implementa um cadastro de 
clientes de uma loja qualquer (rede utilizando 
RMI)
• Lado cliente: interface gráfica
• Lado servidor: modelo e lógica de negócios para 
cadastrar, remover e buscar clientes
51
Proxy Remoto
• Representação da solução com Proxy
Nosso objeto real atuará como 
um servidor, neste caso de 
cadastro: a partir dele 
poderemos acessar outros 
objetos do domínio
Será o substituto do nosso 
Subscriber real no cliente 
gerado automaticamente 
quando o objeto é 
chamado via RMI. Contém 
código I/O e de rede
52
Proxy Remoto
//interface remota
public interface RemoteSubscriber extends Remote {
public add(Client client) throws RemoteException {};
public remove(Client client) throws RemoteException {};
public search(Client client) throws RemoteException {};
}
//criação de uma implementação remota: este é o objeto real
public class Subscriber extends UnicastRemoteObject implements RemoteSubscriber {
List<Client> clients = new ArrayList<Client>();
public Subscriber() throws RemoteException {};
public add(Client client) throws RemoteException { clients.add (client) };
public remove(Client client) throws RemoteException { clients.remove(client); };
public remove(Client client) throws RemoteException { clients.search(client); };
}
53
Proxy Remoto
//essa trecho da classe no servidor que disponibiliza o nosso objeto servidor remoto 
//no registro RMI
public class AplicaçãoServidora {
public static void main(String args[]) {
Subscriber s = new Subscriber();
Naming.rebind(“//127.0.0.1/RemoteSubscriber”, s);
}
}
Registra o nosso objeto 
remoto servidor aqui! Agora 
aplicações em outras 
máquinas podem chamá-lo!
54
10/04/2010
10
Proxy Remoto
//essa classe é o cliente do nosso objeto remoto (executada em outra máquina)
public class TesteClienteRemoto {
public static void main(String args[]) {
RemoteSubscriber rs = (RemoteSubscriber) 
Naming.lookup(“rmi://127.0.0.1/RemoteSubscriber”);
Cliente cli = rs.buscarCliente(“Roberto”);
System.out.println(c.getInfo());
}
} Cliente por não ser um tipo nativo deve 
implementar interface Remote e estender 
Serializable para poder ser utilizado via RMI. 
Nossa aplicação conhece somente sua interface
Busca pelo objeto através 
da localização e nome de 
registro fornecido
55
Proxy Remoto
O que RMI faz...
Cria um que Stub
realiza a chamada e 
implementa o código 
I/O e de rede
Cria um Skeleton que 
recebe as chamadas e 
manipula o objeto real
56
Proxy Virtual
• Proxy Virtual
– Substitui um objeto real cuja criação pode ser 
demasiado onerosa
• Tráfego, largura e banda de rede
• Capacidade de processamento
• Memória disponível
– Exemplo
• Uma aplicação de uma loja que carrega uma imagem de um 
produto no estoque
• Essa imagem é um objeto remoto
• Enquanto o objeto com a imagem não é carregado exibir 
uma mensagem Carregando...
57
Proxy Virtual
Pilha de Objetos da Aplicação
Cliente
ImageProxy
ImageIcon
paintIcon()
paintIcon() possui um 
código que verifica se a 
imagem está disponível...
Outra 
máquina...
Criação do ImageIcon é 
onerosa pois sua imagem 
é carregada via rede!
58
Proxy Virtual
• Criação de objetos sob demanda
• Adiar o curso integral de criação e inicialização do 
objeto até o momento em que for necessário utilizá-lo
– Carregamento de páginas de um documento muito grande
» Somente as páginas visualizadas são carregadas do disco 
rígido para a memória RAM
» Uso racional de memória
____
____
____
____
____
____
__
____
____
____
____
____
____
_
59
Proxy Virtual
Possui uma referência para 
ImageIcon: encapsula a 
criação de ImageIcon a partir 
do carregamento de uma 
imagem. Enquanto a imagem 
não for carregada exibe 
mensagem “Carregando...”
Depois que for possível criar o 
ImageIcon com a imagem 
carregada, o ImageProxy se utiliza 
dos métodos de ImageIcon
60
10/04/2010
11
Proxy
• Conseqüências
– Introduz um nível de referência indireta
• Permite que o objeto resida em um outro servidor , em 
um espaço de endereçamento diferente (proxy remoto)
• Permite que o objeto seja carregado da base somente 
quando necessário, sob demanda (proxy virtual)
61
Proxy
• Diferenças?...
– O que há de diferente do proxy ser remoto, virtual 
ou de proteção é o seu propósito porém...
– Todos eles interceptam a chamada de um método 
pelo cliente, tal interceptação pode:
– Disparar requisições em um objeto remoto (proxy atuando 
como procurador do objeto real)
– Fornecer um substituto enquanto o objeto real é criado (proxy 
atuando como substituto)
– Proteger o objeto de interesse (proxy atuando como protetor)
62
Chain of Responsibility
• Intenção
– Evitar o acoplamento entre objetos solicitantes e 
atendentes permitindo que mais de um objeto 
tenha a oportunidade de tratar a solicitação.
– Repassar a solicitação para uma cadeia de objetos 
atendentes até que algum deles seja capaz de 
tratá-la.
Encadeamento de responsabilidades 
para o tratamento de solicitações!
63
Chain of Responsibility
• Representação arquitetural
Tratador ou Processador possui 
sempre uma referência para ele 
mesmo: forma o sentido da 
cadeia de tratamento!
O método que 
delega a 
responsabilidade 
para um membro 
da cadeia 
64
Chain of Responsibility
• Exemplo
– Um programa que realiza a conversão de um valor 
numérico para extenso
– Estratégia 
• Dividir o valor entre a casas decimais
• Pegar o resto e encaminhar para o próximo da cadeia
Milhar
(1000 até 999.999
Centena
(100 até 999)
Unidade
(1 até 9)
Dezena
(10 até 99)
Trata divisão por 1000 e delega resto
Trata divisão por 100 e delega resto
Trata divisão por 10 edelega resto
65
Chain of Responsibility
• Aplicação do padrão no exemplo...
Referência para 
sucessor deve 
respeitar a ordem da 
cadeia: de milhar para 
centena, de centena 
dezena e de dezena 
para unidade
66
10/04/2010
12
Chain of Responsibility
• Código
public abstract class Conversor {
protected Processador sucessor;
public abstract String converterValorParaExtenso();
public void setSucessor(Processador sucessor) {
this.sucessor = sucessor;
}
}
public class ConversorDezena extends Conversor {
public ConversorDezena() {
sucessor = new ConversorUnidade();
this.sucessor = sucessor;
}
} 67
Chain of Responsibility
//continuação da classe ConversorDezena
public String converterValorParaExtenso(int valor) {
String aux = “”;
int resto = (valor % 10);
int quociente = (valor / 10); 
if ((valor >= 10) && (valor <=19)) {
switch (valor) {
case 10: aux = “dez”; break;
case 11: aux = “onze”;break;
...
case 19: aux = “dezenove”; 
}
}
}
68
Chain of Responsibility
//continuação do método converterValorParaExtenso da classe ConversorDezena 
if (valor >= 20) {
switch(quociente) {
case 2: aux = “vinte”; break;
case 3: aux = “trinta”; break;
case 9: aux = “noventa”; 
}
}
if (valor < 10)
return sucessor.converterValorParaExtenso(valor);
else {
if ((valor >= 20) && (resto != 0))
return aux + “ e ” + sucessor.converterValorParaExtenso(resto);
return aux;
}
}
69
Chain of Responsibility
//ConversorUnidade (sucessor de ConversorDezena)
public class ConversorUnidade extends Conversor {
public String converte (int valor) {
switch(valor) {
case 1: return “um”;
case 2: return “dois”;
case 3: return “três”;
...
case 9: return “nove”;
}
}
}
70
Chain of Responsibility
public class ClienteTeste {
public static void main(String args[]) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
Conversor conversor = new ConversorDezena();
String s = null;
int valor = 0 ;
System.out.println(“Informe um valor”);
try {
s = br.readLine();
valor = Integer.parseInt(s);
} catch (IOException ioe) { 
System.out.println(ioe.getMessage());
}
System.out.println(“O valor ”+valor+” por extenso”
+conversor.converterValorParaExtenso(valor));
}
}
Baixo acoplamento: 
cliente desconhece os 
responsáveis ou a 
composição da cadeia de 
composições.
71
Chain of Responsibility
• Conseqüências
– Evita que um objeto (client) seja forçado a tomar 
conhecimento do outros (handlers)
– O objeto só precisa saber que o pedido foi tratado 
apropriadamente
– A estrutura da cadeia não precisa ser conhecida
• Recursividade Horizontal
– Flexibilidade na atribuição de responsabilidades 
para objetos (subclasses, alteração dinâmica da 
cadeia)
– Sucesso no tratamento do pedido não é garantido
72
10/04/2010
13
Flyweight
• Intenção
– Usar compartilhamento para suportar 
eficientemente grandes quantidades de objetos 
de glanularidade fina
73
Flyweight
• Alta glanularidade: uma aplicação pode 
demandar o uso de centenas ou milhares de 
pequenos objetos ao mesmo tempo
– Como reduzir o número de objetos
– Será que esses objetos possuem características 
comuns?
74
Flyweight
• Explorando os estados de objetos 
(características)
– Estados instrísecos: imutável, estado 
compartilhado
– Estados extrínsecos: mutável, estado não 
compartilhado
75
Flyweight
• Aplicação 
– Separar a parte mutável da imutável
– Criar uma flyweight factory que instancie 
flyweights e faça com que os clientes as 
compartilhem
– Garantir que os clientes usarão a factory em vez 
de construírem eles mesmos as instâncias da 
classe Flyweight. 
• Singleton de pool de objetos
76
Flyweight
• Arquitetura do padrão
77
Flyweight
• Um editor de texto que possui uma letra e sua 
representação (estilo)
– Estado instríseco: letra
• É imutável, o símbolo de uma letra pode ser 
compartilhada pois não muda
– Estado extrínseco: estilo
• É mutável, a representação de uma letra (fonte, cor, 
tamanho) pode ser alterada.
78
10/04/2010
14
Flyweight
public interface Flyweight {
public void exibe (String f, int tam, String cor);
}
public class Letra implements Flyweight {
private char simbolo;
public Letra(char simbolo) {
this.simbolo = simbolo;
}
public char getSimbolo() {
return simbolo;
}
public void exibe (String f, int tam, String cor) {};
}
79
Flyweight
public class Estilo implements Flyweight {
private String fonte;
private int tam;
private String cor;
private Letra letra;
public Estilo(String fonte, int tam, String cor, Letra letra) {
this.fonte = fonte;
this.cor = cor;
this.tam = tam;
this.letra = letra;
}
//getters & setters
...
public void exibe (String f, int tam, String cor) {};
} 80
Flyweight
public class LetraFactory {
Letra[] alfabeto = new Letra[26];
static int quant = 0;
Letra letra;
public Letra get(char c) {
Letra l;
for (int i =0; i< quant; i++) {
if (alfabeto[i] != null)
if (alfabeto[i].getSimbolo() == c)
return alfabeto[i];
}
letra = new Letra(c);
alfabeto[quant++] = letra;
return letra;
}
81
Flyweight
public class Main {
public static void main(String args[]) {
LetraFactory lf = new LetraFactory();
Flyweight[] texto = new Estilo();
texto[0] = new Estilo(“ARIAL”, 12, “preto”, lf.get(‘h’));
texto[1] = new Estilo(“ARIAL”, 12, “preto”, lf.get(‘e’));
texto[2] = new Estilo(“ARIAL”, 12, “preto”, lf.get(‘l’));
texto[3] = new Estilo(“ARIAL”, 12, “preto”, lf.get(‘l’));
texto[4] = new Estilo(“COURIER”, 12, “preto”, 
lf.get(‘o’));
}
82
Flyweight
• Conseqüências
– Compartilhamento de objetos a fim de reduzir 
memória alocada
– Controle da criação de objetos com estados 
distintos
– Centraliza a responsabilidade em objetos 
compartilhados de glanularidade fina
83

Continue navegando