Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Criar uma relação de dependência do
tipo um-para-muitos, de tal forma que o
lado “muitos” seja notificado quando de
uma mudança do lado “um”.
Objetivo é evitar acoplamento forte para
o relacionamento entre classes.
O lado que notifica alterações não
necessita limitar o número de
“notificados”
4-jun-09
Leandro Tonietto
230
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exemplo em [1]:
Aplicação de planilha eletrônica.
A aplicação deve manter a visualização gráfica dos
dados coerente com o estado atual dos mesmos.
Os gráficos compartilham os mesmos dados para
exibição, mas possuem implementação distinta.
Quando o usuário modifica um valor de uma célula
que contem algum dado do gráfico, todos os
gráficos associados com este dado devem ser
atualizados para manter a coerência da
visualização.
A solução é implementar um objeto (subject) que
possa cuidar dos dados da planilha e notificar aos
gráficos associados (observers) que o dado foi
alterado.
4-jun-09
Leandro Tonietto
231
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exemplo em [1]:
4-jun-09
Leandro Tonietto
232
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Estrutura básica:
4-jun-09
Leandro Tonietto
233
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Estrutura básica:
4-jun-09
Leandro Tonietto
234
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Aplicação:
Quando objetos de dependência em certos
aspectos da aplicação, tendo que se manter
coerentes um ao outro, porém deve ser
possível evoluí-los de forma independente.
Quanto observers devem ser mudados por
algum estado especial de um subject.
Inclusive não possível saber qual será o tipo
concreto de observador, nem a quantidade
de observadores (não deve haver
acoplamento forte entre as partes)
4-jun-09
Leandro Tonietto
235
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Conseqüências:
Permite o reuso independente de subjects e observers.
Acoplamento com classes abstratas para subject e para observer.
Um lado não precisa saber das implementações concretas do outro.
O subject apenas notifica observadores, o que estes fazem com a
notificação é de responsabilidade dos próprios observadores.
Como o subject possui uma coleção de observer, é permitido fazer
comunicação broadcast entre os objetos.
Subject não necessita saber quantos observadores ele tem, ele apenas
propaga a notificação.
Atualizações inesperadas por causa da dependência “cega”.
Como a notificação é geral, os dados sobre ela também são, então há
o custo de detecção das mudanças. Uma solução é fazer mais de um
método notificador no subject, um para cada tipo de notificação. Isto
auxilia o observador a considerar ou descartar notificações.
Outro problema é observadores podem ficar longo tempo para
serem notificados por conta das ações que algum outro
desencadeou.
4-jun-09
Leandro Tonietto
236
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Implementação:
Mapear os observers nos subjects. Subjects possuem
uma coleção de observers, que serão notificados.
É possível utilizar uma estrutura tipo hashtable para
fazer o mapeamento subject-observer. Tem maior
custo de acesso aos observadores.
Um observer pode esperar pela notificação de mais
de um subject ao mesmo tempo. Neste caso, na
operação de update, pode-se passar um ponteiro
para o próprio subject que está gerando a
notificação.
Colocar a notificação no subject x controlar pelo
client.
Melhor no subject, mas deve-se tomar o cuidado de manter
a sincronização das notificações e da atualização dos
estados dos subjects.
4-jun-09
Leandro Tonietto
237
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Implementação:
Deleção do subject pode notificar o observer para
manter a integridade das referências.
Deleção do observer deve prever a desvinculação
com o subject. Operação removeObserver() no
subject.
Cuidar para atualizar estado do subject antes da
notificação.
Notificação parametrizada X sem parâmetro
Na parametrizada, as mudanças são informadas na
notificação. Pode enviar mudanças desnecessárias.
Sem parâmetros na notificação, os observadores devem
buscar as mudanças de interesse diretamente do subject.
Não envia mudanças desnecessárias, porém implica em
buscar cada mudança em separado.
4-jun-09
Leandro Tonietto
238
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Implementação:
Listas de observadores diferentes para notificações
diferentes. Evita chamadas desnecessárias aos
observadores que interessados em mudanças ou
eventos específicos.
Uso de um objeto gerenciador de mudanças /
notificações pode ser interessante. Por exemplo,
caso um observador deve esperar pela notificação
em seqüência de diversos subjects. O objeto
gerenciador pode controlar as notificações e
notificar o observador apenas no fim.
4-jun-09
Leandro Tonietto
239
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exemplo:
Classe que implementa um Timer. O objeto timer pode ser usado
para contabilizar e notificar o tempo de processamento de uma
determinada operação.
Também um componente gráfico pode exibir que implementa um
cronometro, fazendo uso de um objeto Timer.
A cada clock (1 segundo) do Timer, o componente gráfico do
cronômetro recupera do timer qual é o tempo atual e desenha de
maneira formatada na interface.
Ainda, é possível mostrar uma formatação diferenciada para o
cronômetro quando o foi solicitado a parada do timer.
4-jun-09
Leandro Tonietto
240
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exemplo:
4-jun-09
Leandro Tonietto
241
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exercício:
Considere um carregador de arquivo de nível de jogo. O jogo
deve carregar as informações de um nível apenas no início do
mesmo.
Suponha que o arquivo que contenha muitas informações e que
demora muito tempo para carregá-lo.
Afim de não deixar o usuário sem um feedback sobre o que está
acontecendo durante a carga, o projetista do jogo previu uma
caixa de diálogo com uma barra de progresso da carga do nível.
A barra é atualizada a cada etapa lida do arquivo (a cada objeto
ou a cada n-bytes).
Para tanto, o carregador de nível deve informar á quantidade
dados lidos, ou a última etapa lida ou ainda, o percentual lido
arquivo.
Faça o diagrama de classes para resolver esta situação
usando o pattern Observer.
4-jun-09
Leandro Tonietto
242
Behavioral
Behavioral Patterns
Patterns –– Observer
Observer
Exercício:
4-jun-09
Leandro Tonietto
243
Download

Observer - Unisinos