ing. del software b il pattern observer simone magnolini

32
Ing. del software B Il Pattern “Observer” Simone Magnolini

Upload: demetrio-manzi

Post on 01-May-2015

220 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Ing. del software B Il Pattern Observer Simone Magnolini

Ing. del software B

Il Pattern “Observer”

Simone Magnolini

Page 2: Ing. del software B Il Pattern Observer Simone Magnolini

Definire una dipendenza uno a molti fra oggetti, in modo tale che se un

oggetto cambia il suo stato, tutti gli oggetti dipendenti da questo ricevano

una notifica e si aggiornino automaticamente.

Scopo

Page 3: Ing. del software B Il Pattern Observer Simone Magnolini

Un esempio concreto

Prendiamo ad esempio questa stessa presentazione:

L'uno: la presentazione, ha uno stato (il numero della slide ad esempio) che pubblica, per questo in generale si identifica come publisher o subject.

La relazione non è unidirezionale, chiunque può intervenire per cambiare lo stato della presentazione

I molti: le persone presenti in aula, sono “interessate” allo stato del soggetto che hanno sottoscritto di osservare (tramite il loro ingresso in aula) per questo si identificano come subscriber o observer

Page 4: Ing. del software B Il Pattern Observer Simone Magnolini

Doveri e responsabilità

Presentazione

Mantenere uno stato, cambiarlo, restituirlo

Inoltre in un qualche modo quando cambia stato deve comunicare la modifica avvenuta, come ad esempio...

Pubblico

Reagire al cambio di stato “nel modo opportuno”

Modificare lo stato di ciò che sta osservando

Page 5: Ing. del software B Il Pattern Observer Simone Magnolini

Struttura observer

Presentazione

getState()

setState()

statoPresentazione

Alunno 1

reagisci()

statoAlunno

Alunno N

reagisci()

statoAlunno

Alunno 2

reagisci()

statoAlunno

Page 6: Ing. del software B Il Pattern Observer Simone Magnolini

Struttura observer

Presentazione

getState()

setState()

statoPresentazione

Alunno 1reagisci()

statoAlunno

Alunno Nreagisci()

statoAlunno

Alunno 2reagisci()

statoAlunno

Ascoltatore

reagisci()

Page 7: Ing. del software B Il Pattern Observer Simone Magnolini

Struttura observer

Presentazione

getState()

setState()

statoPresentazione

Alunno 1reagisci()

statoAlunno

Alunno Nreagisci()

statoAlunno

Alunno 2reagisci()

statoAlunno

Ascoltatore

reagisci()

Lezione

aggiungi(Ascoltatore)

rimuovi(Ascoltatore)

notifica()

Page 8: Ing. del software B Il Pattern Observer Simone Magnolini

Struttura observer

Presentazione

getState()

setState()

statoPresentazione

Alunno 1reagisci()

statoAlunno

Alunno Nreagisci()

statoAlunno

Alunno 2reagisci()

statoAlunno

Ascoltatore

reagisci()

Lezione

aggiungi(Ascoltatore)

rimuovi(Ascoltatore)

notifica()

Page 9: Ing. del software B Il Pattern Observer Simone Magnolini

Struttura observer

ConcreteSubject

getState()

setState()

subjectstate

ConcreteObserverupdate()

observerState

Observer

update()

Subject

attach(Observer)

detach(Observer)

notify()

Page 10: Ing. del software B Il Pattern Observer Simone Magnolini

Anche conosciuto come

Publish-Subscribe

Dependents

Java Delegation Event Model

Intuitivamente correlato a tutti i paradigmi di programmazione “a eventi”

Classificazione

Comportamentale

Focalizzato sulle relazioni run-time tra oggetti

Il Pattern “Observer”

Page 11: Ing. del software B Il Pattern Observer Simone Magnolini

Viste multiple dello stato pubblicato

Più di un formato di visualizzazione

Devono essere coerenti

Viste multiple interattive, che permettono la modifica dello stato

Occorre aggiornare anche le altre viste

Devono essere coerenti

Paradigma a eventi (non c’entra per forza una GUI)

Es. il meccanismo dei trigger in una base di dati relazionale

Motivazione

Page 12: Ing. del software B Il Pattern Observer Simone Magnolini

A B C D44 33 333 88

ABCD

0

50

100

150

200

250

300

350

A B C D

Esempio classico

Page 13: Ing. del software B Il Pattern Observer Simone Magnolini

Se un’astrazione presenta due aspetti in cui uno è dipendente dall’altro. Separandoli è possibile riutilizzarli

Se cambiamenti ad un oggetto hanno ripercussioni su altri oggetti il cui numero è variabile, o comunque non è noto a priori

Se un oggetto deve inviare messaggi ad altri oggetti senza sapere esattamente di che tipo sono

legami di dipendenza deboli (disaccoppiamento)

Applicabilità

Page 14: Ing. del software B Il Pattern Observer Simone Magnolini

Partecipanti: Subject

“Conosce” tutti gli observer

Chiunque implementi l’interfaccia observer può osservare il soggetto

Offre metodi per:

L’aggiunta di un osservatore (attach)

La rimozione di un osservatore (detach)

In java potrebbe essere implementata come abstract

Senza istanze, ma con dei metodi implementati

Page 15: Ing. del software B Il Pattern Observer Simone Magnolini

Partecipanti: Observer

Fornisce un’interfaccia

Tutti gli osservatori devono ereditarla per ottenere gli aggiornamenti del soggetto

In java potrebbe essere implementata come interface

Senza istanze né metodi implementati

Page 16: Ing. del software B Il Pattern Observer Simone Magnolini

Partecipanti: ConcreteSubject

Memorizza lo stato che interessa ai ConcreteObserver

Lo ritorna, in generale, con il metodo getState() nel caso Java

NOTA: Bisogna chiamare notify() all’interno di setState()

Al termine della modifica di stato il cambiamento viene notificato a tutti gli osservatori, anche a chi l’ha

prodotto

Page 17: Ing. del software B Il Pattern Observer Simone Magnolini

Partecipanti: ConcreteObserver

Mantiene un riferimento ad un oggetto ConcreteSubject di interesseIn realtà un singolo osservatore può guardare più soggetti

Memorizza lo stato

Quello che dovrebbe essere sincronizzato/aggiornato

Implementa l’interfaccia Observer

Implementa il metodo update(), quest’ultimo aggiorna lo stato memorizzato per mantenere la sincronia

Page 18: Ing. del software B Il Pattern Observer Simone Magnolini

Collaborazioni: iscrizione

aConcreteSubject

aConcreteObserver

attach(this)

attach(this)

notify ()

update()

update()

anotherConcreteObserver

getState()

getState()

Page 19: Ing. del software B Il Pattern Observer Simone Magnolini

Collaborazioni: aggiornamento

aConcreteSubject

aConcreteObserver

setSate()

notify ()

update()

update()

anotherConcreteObserver

getState()

getState()

Page 20: Ing. del software B Il Pattern Observer Simone Magnolini

Conseguenze

Disaccoppiamento tra le classi

Il Subject conosce solo l’interfaccia Observer (non chi l’osserva)

Per ricevere le notifiche un oggetto qualunque deve solo implementare l’interfaccia Observer

Broadcast

I messaggi possono essere notificati a tutti gli Observer chiamando notify()

Si possono rimuovere e aggiungere Observer a piacere

Il problema degli update non attesi

Gli Observer non si conoscono

Non possono sapere i reali effetti di operazioni compiute sul Subject

Possono esserci effetti a cascata di aggiornamenti e sincronizzazioni,anche incompleti

Page 21: Ing. del software B Il Pattern Observer Simone Magnolini

Problemi implementativi

Page 22: Ing. del software B Il Pattern Observer Simone Magnolini

1) Tracciare le dipendenze

Mantenere le associazioni

Il Subject tiene traccia di tutti i propri Observer

Necessario per sapere a chi mandare le notifiche

Efficiente nel caso ideale (pochi Subject, molti Observer)

Il sovraccarico delle strutture dati può diventare significativo se la situazione è invertita (pochi Observer e

molti Subject)

Strutture associative per mappare Subject e Observer (es. Hash Table)

Risparmio dello spazio, ma penalità nel tempo

Page 23: Ing. del software B Il Pattern Observer Simone Magnolini

2) Tanti Subject

Tante cose da osservare

Un Observer può essere interessato alle notifiche di più Subject

Un oggetto che necessità di più strutture dati per funzionare

Es. Un grafico che rappresenta le relazioni tra due entità

In questo caso potrebbe essere utile passare l’oggetto come parametro della notifica per rendere evidente

chi è stato modificato

Page 24: Ing. del software B Il Pattern Observer Simone Magnolini

3) Responsabilità

Chi è il responsabile di iniziare l’invio di notifiche?

Il Subject

Le operazioni che modificano lo stato dell’oggetto chiamano notify()

L’Observer può ignorare il problema

Più operazioni di questo tipo causano molti update consecutivi

Possibile inefficienza

Sicuri problemi con il multithreading!

Gli Observer

Chiamano notify() quando hanno finito di modificare lo stato

Più efficiente, più facile gestire il multithreading

Più responsabilità per gli Observer, che a questo punto diventano dei client non più passivi del Subject

Meno sicuro

Page 25: Ing. del software B Il Pattern Observer Simone Magnolini

4) Distruttori

Distruzione del Subject

In generale, la soluzione migliore è notificare la situazione agli Observer

Non è detto che gli Observer debbano essere distrutti per forza

Se “osservano” più soggetti?

Modifica opportuna al distruttore della classe Subject

E IN JAVA?????

Page 26: Ing. del software B Il Pattern Observer Simone Magnolini

Altri problemi

Auto-consistenza del Subject

Prima del notify() tutti gli aggiornamenti devono essere completi

Non utilizzare protocolli specifici di aggiornamento

Modello push, il Subject inoltra informazioni sulla modifica

Più efficiente, ma meno riusabile

Modello pull, il Subject delega l’aggiornamento agli osservatori

Meno efficiente, ma più riusabile

Osservatori interessati

Per migliorare l’efficienza gli Observer potrebbero fornire al momento dell’iscrizione a cosa sono interessati del Subject

Page 27: Ing. del software B Il Pattern Observer Simone Magnolini

Quando ci sono troppi problemi

ChangeManager èun’istanza del patternMediator ed essendo uniconell’applicazione potrebbeessere un Singleton

Page 28: Ing. del software B Il Pattern Observer Simone Magnolini

Implementazione

ESEMPIO: Un count down java

import java.util.Observable;

import java.util.Observer;

public class Esempio{

public static void main(String[] args){

// istanzio l'oggetto osservatore e l'oggetto da osservare

Osservatore osservatore = new Osservatore();

Osservato osservato = new Osservato();

// aggiungo all'oggetto da osservare l'osservatore

osservato.addObserver(osservatore);

// faccio partire il conto alla rovescia

osservato.contoAllaRovescia(10);

}

}

Page 29: Ing. del software B Il Pattern Observer Simone Magnolini
Page 30: Ing. del software B Il Pattern Observer Simone Magnolini

Implementazione

class Osservato extends Observable {

public void contoAllaRovescia(int n) {

for ( ; n >= 0; n--) {

// l'oggetto e' cambiato

setChanged();

// notifico il cambiamento all'osservatore

notifyObservers(new Integer(n));

}

}

}

Page 31: Ing. del software B Il Pattern Observer Simone Magnolini

Implementazione

class Osservatore implements Observer {

public void update(Observable oggettoOsservato, Object obj) {

// ottengo il valore di n passato da notifyObservers ad update

int n = ((Integer)obj).intValue();

System.out.println("" + n);

}

}

Page 32: Ing. del software B Il Pattern Observer Simone Magnolini

Ultime note

In Java esistono le interfacce Observer e Observable

Sono “deprecated” dalla versione 1.1

Compatibilità retroattiva

Casi molto semplici, usi in cui il meccanismo a eventi è probabilmente eccessivo

Java Delegation Event Model

Si definiscono “listeners”, “event handlers”