Modulo 18
Design Patterns Behavioral
Categoria Behavioral
z
Questi pattern sono dedicati all'assegnamento di
responsabilità tra gli oggetti e alla creazione di
algoritmi.
z
Una caratteristica comune in questi pattern è il
supporto per seguire le comunicazioni che
avvengono tra le classi.
z
l'utilizzo di questi pattern permette di dedicarsi
principalmente alle connessioni tra oggetti lasciando
in disparte la gestione dei flussi di controllo.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
2
1
I Design Pattern Behavioral
Design
Patterns
Chain of
Responsability
Descrizione
Evita l’accoppiamento di chi manda una richiesta con chi la riceve
dando a più oggetti la possibilità di gestire la richiesta.
Command
Incapsula una richiesta in un oggetto in modo da poter eseguire
operazioni che non si potrebbero eseguire.
Interpreter
Dato un linguaggio, definisce una rappresentazione per la sua
grammatica ed un interprete per le frasi del linguaggio.
Iterator
Fornisce una modalità di accesso agli elementi di un oggetto aggregato
in modo sequenziale senza esporre la rappresentazione sottostante
Mediator
Definisce un oggetto che incapsula il modo in cui un insieme di oggetti
interagisce in modo da permettere la loro indipendenza
Memento
Cattura e porta all'esterno lo stato interno di un oggetto senza violare
l'incapsulazione in modo da ripristinare il suo stato più tardi
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
3
I Design Pattern Behavioral (2)
Design
Patterns
Observer
State
Strategy
Template method
Visitor
Descrizione
Definisce una dipendenza 1:N tra oggetti in modo che se uno cambia
stato gli altri siano aggiornati automaticamente
Permette ad un oggetto di cambiare il proprio comportamento a seconda
del suo stato interno, come se cambiasse classe di appartenenza
Definisce una famiglia di algoritmi, li incapsula ognuno e li rende
intercambiabili in modo da cambiare in modo indipendente dagli
utilizzatori
Definisce lo scheletro di un algoritmo in un'operazione lasciando definire
alcuni passi alle sottoclassi
Rappresenta un'operazione da fare sugli elementi della struttura di un
oggetto. Lascia definire nuove operazioni senza cambiare classe degli
elementi
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
4
2
Chain of Responsability
z
Scopo:
z
Evitare l’accoppiamento tra l’oggetto che invia
una richiesta e l’oggetto che la riceve, offrendo a
più oggetti la possibilità di gestire la richiesta.
z
Formare una catena di oggetti riceventi e
trasmettere la richiesta lungo la catena, fino a
quando un oggetto non la gestisce.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
5
Chain of Responsability
(Struttura)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
6
3
Chain of Responsability
(Diagramma delle istanze)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
7
Chain of Responsability
(Esempio)(1)
z
Problema:
z
Gestire l’aiuto contestuale di un’applicazione, in
modo che se l’aiuto specifico per un controllo non
esiste, si faccia riferimento ad un aiuto sempre più
generale, fino ad arrivare all’aiuto relativo
all’intera applicazione
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
8
4
Chain of Responsability
(Esempio)(2)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
9
Chain of Responsability
(Esempio)(3)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
10
5
Chain of Responsability
(Esempio)(4)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
11
Chain of Responsability:
Esercizio
z
Una azienda commerciale deve gestire le richieste di credito dei
clienti (customers). Internamente l’azienda si organizza in diversi
livelli di responsabilità.
z
Al livello più basso (vendor) viene consentito l’approvazione di
richieste fino a un importo determinato.
z
Le richieste che superano questo importo vanno gestite da un
livello superiore (sales manager), il quale ha un altro importo
massimo da gestire.
z
Richieste che vanno oltre quest’ultimo importo, vanno gestire da
un livello più alto ancora (client account manager).
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
12
6
Chain of Responsability:
Esercizio
z
Diagramma UML:
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
13
Chain of Responsability:
Esercizio
z
Partecipanti:
z Handler: classe CreditRequestHandler.
z
z
z
ConcreteHandler: classi Vendor, SalesManager e
ClientAccountManager.
z
z
z
Specifica una interfaccia per la gestione delle richieste.
In modo opzionale, implementa un riferimento a un oggetto
successore.
Gestiscono le richieste che corrispondono alla propria responsabilità.
Accedono ad un successore (se è possibile), nel caso in cui la
ichiesta non corrisponda alla propria gestione.
Client: classe Customer.
z
Inoltra una richiesta a un ConcreteHandler della catena.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
14
7
Chain of Responsability:
Implementazione in Java (1)
z
Nodo della catena… (senza logica di controllo)
public abstract class CreditRequestHandler {
private CreditRequestHandler successor;
public void setSuperiorRequestHandler( CreditRequestHandler theSuperior ) {
successor = theSuperior;
}
public void creditRequest( int amount )
throws CreditRequestHandlerException {
forwardCreditRequest( amount );
}
protected void forwardCreditRequest( int amount )
throws CreditRequestHandlerException {
if( successor != null )
successor.creditRequest( amount );
else
throw new CreditRequestHandlerException();
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
}
}
15
Chain of Responsability:
Implementazione in Java (2)
z
Una delle classi derivate … (con la logica di
controllo)
public class SalesManager extends CreditRequestHandler {
public void creditRequest( int amount )
throws CreditRequestHandlerException {
if( amount <= 1000 )
if( Math.random() < .3 )
System.out.println( "Accepted by Sales Manager." );
else
System.out.println( "Not accepted by Sales Manager." );
else
forwardCreditRequest( amount );
}
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
16
8
Chain of Responsability:
Implementazione in Java (3)
Esempio di utilizzo
z
public class ChainOfResponsibilityExample {
public static void main(String[] arg)
throws CreditRequestHandlerException {
ClientAccountManager clientAccountMgr =
new ClientAccountManager();
SalesManager salesMgr = new SalesManager();
Vendor vendor = new Vendor();
vendor.setSuperiorRequestHandler( salesMgr );
salesMgr.setSuperiorRequestHandler( clientAccountMgr );
Customer customer = new Customer();
int i=500;
while( i <= 2500 ) {
System.out.println( "Credit request for : $"+ i );
customer.requestCredit( vendor, i );
i += 500;
}
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
}
17
Chain of Responsability:
Commenti
z
La chain of responsability è un meccanismo debole
di propagazione dei messaggi:
z
z
Approccio cooperativo
Nessuno può assicurare che un handler rilasci il controllo
correttamente ad un handler successivo
z Win16 e Win32 soffrivano di questo problema nel controllo
dei processi
z
Meccanismo snello se implementato correttamente
z
In java, un approccio alterativo è rappresentato dal
meccanismo di gestione delle eccezioni
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
18
9
Command
z
Scopo:
z
Incapsulare una richiesta in un oggetto, quindi
lasciare al programmatore la possibilità di
parametrizzare il codice chiamante per richieste di
diverso tipo, e operazioni di tipo undoable
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
19
Command (Struttura)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
20
10
Command (Esempio)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
21
Command (Esempio) (2)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
22
11
Command (Esempio) (3)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
23
Command (Esempio) (4)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
24
12
Command (Partecipanti)
z
Command
z
z
ConcreteCommand (PasteCommand, OpenCommand)
z
z
z
Crea un oggetto ConcreteCommand e imposta il suo receiver.
Invoker (MenuItem)
z
z
Definisce il collegamento tra un oggetto receiver e un’azione
Implementa Execute invocando le corrispondenti operazioni di Receiver.
Client (Application)
z
z
dichiara un’interfaccia per eseguire un’operazione
Richiede all’oggeto Command di evadere la richiesta
Receiver (Document, Application)
z
Responsabile dell’esecuzione dell’operazione associata a seguito della
richiesta
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
25
Command:
Esercizio (1)
z
Un telecomando universale consente di gestire diversi tipi di
elettrodomestici (TV di diversi modelli e marche, Hi-Fi, ecc.).
z
Durante la fase di progettazione del telecomando si riesce a definire il
numero di tasti e la etichetta di ogni singolo tasto, ma non le operazione
concrete da eseguire (vale dire, il segnale particolare da spedire
all’elettrodomestico).
z
Si spera che queste operazioni vengano aggiunte, ulteriormente, al
momento di configurare il telecomando (ad esempio, l’utente potrebbe
scaricare da internet le classi che li servono per i propri
elettrodomestici).
z
Il problema consiste nella progettazione di una classe (telecomando), in
grado di inoltrare richieste verso oggetti che saranno noti solo in fasi
successive di sviluppo.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
26
13
Command:
Applicazione del pattern
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
27
Coomand:
Implementazione in Java (1)
z
Si creano le interfacce delle classi che devono
implementare i prodotti di tutte le famiglie.
public interface Media { }
public interface Player {
public void accept( Media med );
public void play( );
}
public interface Recorder {
public void accept( Media med );
public void record( String sound );
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
28
14
Command:
Implementazione in Java (2)
z
Implementazione di un Command
class TVPowerCommand implements Command {
private TV theTV;
public TVPowerCommand ( TV someTV ) {
theTV = someTV ;
}
public void execute() {
theTV.power();
}
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
29
Command:
Implementazione in Java (3)
z
Implementazione del receiver
public class TV {
public static final int ON = 1;
public static final int OFF = 0;
private int power = OFF;
private int volume = 0;
private int channel = 2;
public void power() {
if( power == OFF ) {
power = ON;
System.out.println( "The TV is ON." );
} else {
power = OFF;
System.out.println( "The TV is OFF." );
}
}
...
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
}
30
15
Command e Functor
z
I command assomigliano ai functor (oggetti
funzione)
z
Tuttavia:
z
z
Nei functor l’attenzione è posta nella
parametrizzazione dell’operazione
I command sono principalmente oggetti di
collegamento tra l’invoker e il receiver
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
31
Iterator
z
Scopo:
z
Fornire un modo per accedere agli elementi di un
oggetto aggregato in sequenza senza
preoccuparsi della rappresentazione sottostante
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
32
16
Iterator (Struttura)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
33
Iterator (Esempio)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
34
17
Iterator:
Esercizio
z
Il percorso di un viaggiatore è rappresentato come
una collezione ordinata di oggetti, dove ogni oggetto
rappresenta un luogo visitato.
z
La collezione può essere implementata in base a
array, una linked list o qualunque altra struttura.
z
Una applicazione sarebbe interessata in poter
accedere agli elementi di questa collezione in una
sequenza particolare, ma senza dover interagire
direttamente con il tipo di struttura interna.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
35
Iterator in Java
z
Le collection in Java hanno implementano il
pattern Iterator a partire dalla introduzione
nella versione 1.3
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
36
18
Iterator:
Applicazione del pattern
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
37
Iterator:
Implementazione in Java (1)
import java.util.LinkedList;
import java.util.ListIterator;
public class IteratorExample {
public static void main( String[] arg ) {
LinkedList tour = new LinkedList();
tour.add( "Santiago" );
tour.add( "Buenos Aires" );
tour.add( "Atlanta" );
tour.add( "New York" );
tour.add( "Madrid" );
ListIterator travel = tour.listIterator();
System.out.println( "Percorso andata" );
while( travel.hasNext() )
System.out.println( ((String) travel.next()) );
System.out.println( "Percorso ritorno" );
while( travel.hasPrevious() )
System.out.println( ((String) travel.previous()) );
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
}
38
}
19
Observer
z
Scopo:
z
Definire una associazione uno-a-molti tra oggetti,
in modo che quando un oggetto cambia stato,
tutte le sue associazioni ne vengano notificate e
aggiornate automaticamente.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
39
Observer
(Struttura)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
40
20
Observer
(Interazione tra gli oggetti)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
41
Observer
(Esempio)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
42
21
Observer:
Esercizio
z
Ad un oggetto (Subject) vengono comunicati diversi
numeri.
z
Questo oggetto decide in modo casuale di cambiare
il suo stato interno, memorizzando il numero ad
esso proposto.
z
Altri due oggetti incaricati del monitoraggio
dell’oggetto descritto (un Watcher e un
Psychologist), devono avere notizie di ogni suo
singolo cambio di stato, per eseguire i propri
processi di analisi.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
43
Observer:
Esercizio
z
Diagramma UML:
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
44
22
Observer:
Implementazione in Java (1)
z
Implementiamo il Subject
import java.util.Observer;
import java.util.Observable;
public class ObservedSubject extends Observable {
private int value = 0;
public void receiveValue( int newNumber ) {
if (Math.random() < .5) {
System.out.println( "Subject : I like it, I’ve changed my internal value." );
value = newNumber;
this.setChanged();
} else
System.out.println( "Subject : I not interested in the number.");
this.notifyObservers();
}
Luigi Troiano
di Produzione del{Software:
Modulo
18
public
int- Tecnologie
returnValue()
return
value;
}
45
}
Observer:
Implementazione in Java (2)
z
Implementazione di un Observer
import java.util.Observer;
import java.util.Observable;
public class Psychologist implements Observer {
private int countLower, countHigher = 0;
public void update(Observable obs, Object arg) {
int value = ((ObservedSubject) obs ).returnValue() ;
if( value <= 5 ) countLower++;
else countHigher++;
}
public String opinion() {
float media;
if( (countLower + countHigher ) == 0 )
return( "The Subject doesn’t like changes.");
else if( countLower > countHigher )
return( "The Subject likes little numbers.");
else if ( countLower < countHigher )
return( "The Subject likes big numbers.");
else
return( "The Subject likes little numbers and big numbers.");
Luigi}Troiano - Tecnologie di Produzione del Software: Modulo 18
}
46
23
Observer:
Implementazione in Java (3)
Esempio di utilizzo
z
public class ObserverExample {
public static void main (String[] args) {
ObservedSubject s = new ObservedSubject() ;
Watcher w = new Watcher();
Psychologist p = new Psychologist();
s.addObserver( w );
s.addObserver( p );
for(int i=1;i<=10;i++){
System.out.println( "Main : Do you like the number " + i +"?" );
s.receiveValue( i );
}
System.out.println( "The Subject has changed " + w.observedChanges()
+ " times the internal value.");
System.out.println("The Psychologist opinion is:" + p.opinion() );
}
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
47
Observer in Java
z
Java estende il modello originalmente
proposto dai GoF, in modo di poter associare
un singolo Observer a più Subject
contemporaneamente.
z
Questo è consentito dal fatto che il metodo di
update dell’Observer riceve come parametro
un riferimento al Subject che fa la notifica,
consentendo al primo di conoscere quale di
tutti i Subject la ha originato.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
48
24
Strategy
z
Scopo:
z
Definire una famiglia di algoritmi, incapsulandoli
ognuno, e rendendoli intercambiabili. Strategy
consente di variare l’algoritmo indipendentemente
dal client.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
49
Strategy (Struttura)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
50
25
Strategy (Esempio)
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
51
Strategy:
Esercizio
z
z
z
z
z
La progettazione di una applicazione che offre delle funzionalità
matematiche, considera la gestione di una apposita classe
(MyArray) per la rappresentazione di vettori di numeri.
Tra i metodi di questa classe si ha definito uno che esegue la
propria stampa.
Questo metodo potrebbe stampare il vettore nel seguente modo
(chiamato, ad es. MathFormat):.
{ 12, -7, 3, … }
oppure di questo altro modo (chiamato, ad. es. SandardFormat):
Arr[0]=12 Arr[1]=-7 Arr[2]=3 …
E’ anche valido pensare che questi formati potrebbero
posteriormente essere sostituiti da altri.
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
52
26
Strategy:
Applicazione del pattern
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
53
Strategy:
Implementazione in Java (1)
z
La classe astratta ArrayDisplayFormat
public interface ArrayDisplayFormat {
public void printData( int[] arr );
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
54
27
Strategy:
Implementazione in Java (2)
z
Implementazione di una strategy
public class StandardFormat implements ArrayDisplayFormat {
public void printData( int[] arr ) {
System.out.print( "{ " );
for(int i=0; i < arr.length-1 ; i++ )
System.out.print( arr[i] + ", " );
System.out.println( arr[arr.length-1] + " }" );
}
}
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
55
Strategy:
Implementazione in Java (3)
z
Implementazione del context
public class MyArray {
private int[] array;
private int size;
ArrayDisplayFormat format;
public MyArray( int size ) { array = new int[ size ]; }
public void setValue( int pos, int value ) {array[pos] = value; }
public int getValue( int pos ) { return array[pos]; }
public int getLength( int pos ) { return array.length; }
public void setDisplayFormat( ArrayDisplayFormat adf ) {
format = adf;
}
public void display() {
format.printData( array );
Luigi}Troiano - Tecnologie di Produzione del Software: Modulo 18
}
56
28
Sommario
z
I Behavioral Design Patterns sono un insieme di 11
patterns proposti nel catalogo GOF
z
Essi affrontano il problema di come parametrizzare
l’interazione tra oggetti
z
I pattern considerati sono stati:
z Chain of Responsability
z Command
z Iterator
z Observer
z Strategy
Luigi Troiano - Tecnologie di Produzione del Software: Modulo 18
57
29