Design Pattern
Observer
INGEGNERIA DEL SOFTWARE
Nicola Ferrari
Carta d’identità
Nome
Alias
Dependents
Publish-Subscribe
Classificazione
Observer
Comportamentale, basato su oggetti
Scopo
Definisce una relazione uno a molti tra oggetti, in modo tale che quando un
oggetto cambia stato tutti gli oggetti da lui dipendenti vengono automaticamente
notificati
2
Motivazioni
Un esempio noto a tutti
Il foglio elettronico e le sue opportunità.
I dati in forma tabellare possono essere rappresentati nei
diversi tipi di grafici.
Observer si preoccupa della sincronizzazione automatica fra
tutte queste parti. Cioè l’aggiornamento dei valori di certe celle
provoca il ridisegno dei grafici.
3
Applicabilità
Quando un’astrazione presenta due aspetti,
di cui uno dipende dall’altro.
Quando una modifica ad un oggetto richiede
modifiche ad altri oggetti che dipendono da
questo.
Quando si vuole mantenere un alto livello di
disaccoppiamento fra gli oggetti.
4
I partecipanti
Gli attori (visione globale)
Subject (abstract)
Observer (interface)
ConcreteSubject
ConcreteObserver
5
I partecipanti
Subject
Classe astratta da cui eredita
ConcreteSubject
Tiene i riferimenti ai vari observers
metodi add e remove
attributo observers
Informa gli observers di un avvenuto
cambiamento di stato
metodo notify
6
I partecipanti
Subject (il codice)
notify() delega ad
Observer
l’aggiornamento dello
stato
Mancano le astrazioni di
setState e getState
public abstract Subject {
protected int state;
protected ArrayList observers;
public void add(Observer o) {
observers.add(o);
}
public void remove(Observer o) {
int i = observers.indexOf(o);
if (i>=0) observers.remove(o);
}
public void notify() {
for (int i=0; i<=observers.size();i++) {
Observer o = (Observer) observers.get(i);
o.update();
}
}
….
}
7
I partecipanti
Observer
interfaccia implementata da
ConcreteObserver
ConcreteObserver
Tiene riferimento a Subject per leggere
lo stato
8
Implementazione
ConcreteObserver (il codice)
public class ConcreteObserver implements Observer {
private String id;
private int state;
private Subject subject;
public ConcreteObserver(String Id, Subject subject) {
this.id = Id;
this.subject = subject;
stato = id.length();
update richiede lo stato
}
tramite getState dal soggetto
public void update() {
concreto
state = state+subject.getState();
}
}
9
Ricapitolando
Il metodo notify chiama
il metodo update da
tutti gli Observer
registrati.
Il metodo update a sua
volta richiama getState
di ConcreteSubject per
ottenere il nuovo stato
10
Conseguenze
1.
Accoppiamento astratto fra Subject e
Observer
2.
Supporto
broadcast
3.
Aggiornamenti inattesi
per
comunicazioni
11
Implementazione
Mantenere le associazioni fra soggetti ed
osservatori
1.
Usando una tabella di hash
Un soggetto senza osservatori non occupa spazio
Sarà più oneroso accedere agli osservatori
12
Implementazione
Chi fa partire la notifica?
2.
I metodi di Subject quando modificano il proprio
stato automaticamente chiamano Notify dopo
aver cambiato lo stato del soggetto
Inefficienza nel caso di aggiornamenti multipli
I client devono invocare Notify sull’oggetto al
momento opportuno.
Si corre il rischio di dimenticarsene.
13
Implementazione
Riferimenti a soggetti cancellati
3.
La cancellazione di un soggetto non dovrebbe
produrre riferimenti non validi negli osservatori
Il soggetto notifica ai suoi osservatori la propria
cancellazione in modo che questi possano eliminare il
riferimento al soggetto
14
Implementazione
Evitare protocolli di notifica specifici per
l’osservatore
4.
Le implementazioni prevedono che il soggetto alleghi
nella notifica informazioni addizionali sul cambiamento
avvenuto nell’osservatore
Modello push: si allegano informazione dettagliate
Problema di riusabilità.
Modello pull: non si allega nulla
Gli Observer devono capire cosa è cambiato
15
Implementazione
Incapsulare semantiche complesse di
aggiornamento
5.
Quando la dipendenza fra soggetti e osservatori
è particolarmente complessa, potrebbe essere
richiesto un oggetto che mantenga queste
associazioni
Maggior sincronizzazione fra osservatori e soggetto
16
Utilizzi noti
Gestione degli eventi degli widget di una GUI
Gestione degli eventi di un alarm clock
Model View Control
17
Pattern correlati
Mediator
svolge il ruolo di mediatore fra soggetto e
osservatori
Vedi lucido 16
Singleton
18