SlideShare a Scribd company logo
Lezione 23: Design
    Pattern Comportamentali
         Corso di Ingegneria del Software
       Laurea Magistrale in Ing. Informatica
         Università degli Studi di Salerno



1
Outline



    ✦ Design Pattern Comportamentali
     •   Template Method

     •   Chain of Responsibility




2
Design Pattern Comportamentali




3
Design Pattern Comportamentali



    ✦ Lo scopo comune è affrontare problemi
      che riguardano il modo in cui un oggetto
      svolge la sua funzione, o il modo in cui un
      insieme di oggetti collaborano per
      svolgere un determinato compito




4
Template Method

    ✦ Il problema
     •   Spesso capita di incontrare diversi problemi che si
         risolvono con algoritmi che hanno la stessa
         struttura, ma differiscono in alcune operazioni di
         dettaglio
         ‣   ripetere più volte la struttura comune è una violazione del
             principio DRY
         ‣   si vuole avere la possibilità di riutilizzare la struttura
             comune per reimplementare più semplicemente nuovi
             algoritmi dello stesso tipo




5
Template Method
    ✦ Esempio del problema

         	   public int computeSum(int a[], int n) {
         	   	 int sum=0;
         	   	 int i;
         	   	 for(i=0; i<n; i++)
         	   	 	 sum=sum+a[i];
         	   	 return sum;	 	
         	   }
         	
         	   public int computeProduct(int a[], int n) {
         	   	 int product=1;
         	   	 int i;
         	   	 for(i=0; i<n; i++)
         	   	 	 product=product*a[i];
         	   	 return product;	
         	   }
6
Template Method
    ✦ Esempio del problema
     •   la struttura comune:


            	   public int computeXxx(int a[], int n) {
            	   	 int valore=”valore iniziale”;
            	   	 int i;
            	   	 for(i=0; i<n; i++)
            	   	 	 valore=”combinazione di valore e a[i]”
            	   	 return valore;
            	   }




7
Template Method
    ✦ Soluzione
     •   si definisce una classe “abstract” per lo schema di
         algoritmo
     •   la struttura dell’algoritmo è definita in un metodo
         (“template method”), che richiama altri metodi
         (“hook methods”) per le parti che differiscono tra
         i vari problemi
     •   gli hook methods possono avere una
         implementazione di default, o essere metodi
         “abstract”
     •   per ogni problema concreto si crea una
         sottoclasse che implementa i metodi hook
8
Template Method
    ✦ Esempio di struttura




9
Template Method
       ✦ Esempio di soluzione
     public abstract class Accumulator {
     	 // Template method
     	 public int compute(int a[], int n) {
     	 	 int value=initialValue();
     	 	 int i;
     	 	 for(i=0; i<n; i++)
     	 	 	 value=combine(value, a[i]);
     	 	 return value;
     	 }
     	
     	 // Hook method
     	 public abstract int initialValue();
     	
     	 // Hook method
     	 public abstract int combine(int currentValue, int element);
     }
10
Template Method
       ✦ Esempio di soluzione (continua)



     public class SumAccumulator extends Accumulator {
     	 public int initialValue() {
     	 	 return 0;
     	 }
     	
     	 public int combine(int currentValue, int element) {
     	 	 return currentValue+element;
     	 }
     }




11
Template Method
       ✦ Esempio di soluzione (continua)



     public class ProductAccumulator extends Accumulator {
     	 public int initialValue() {
     	 	 return 1;
     	 }
     	
     	 public int combine(int currentValue, int element) {
     	 	 return currentValue*element;
     	 }
     }




12
Template Method
         ✦ Esempio di soluzione (continua)

     public class CountPositiveAccumulator extends Accumulator {
     	 public int initialValue() {
     	 	 return 0;
     	 }
     	
     	 public int combine(int currentValue, int element) {
     	 	 if (element>0)
     	 	 	 return currentValue+1;
     	 	 else
     	 	 	 return currentValue;
     	 }

     }


13
Template Method

     ✦ Conseguenze
      •   si separa la struttura generale comune a un
          insieme di algoritmi dai dettagli che differiscono,
          consentendo il riuso della prima
      •   si garantisce la coerenza tra le soluzioni a
          problemi analoghi
      •   è possibile applicare la stessa struttura a problemi
          nuovi, inizialmente non considerati




14
Template Method

     ✦ Esempi
      •   numerosi framework utilizzano questo pattern per
          definire applicazioni in cui la struttura generale
          dell’applicazione è fissata, e lo sviluppatore deve
          specificare soltanto gli elementi peculiari
          dell’applicazione corrente
          ‣   Applet
          ‣   Servlet




15
Template Method
     ✦ Nota
      •   questo pattern rappresenta un esempio di
          applicazione del cosiddetto “Hollywood Principle”,
          così denominato dalla “risposta standard” nei
          provini di dilettanti a Hollywood:
               “Don’t call us...We’ll call you.”
      •   l’idea di base di questo principio è che non è il
          codice specifico dell’applicazione a richiamare il
          codice generale presente in una libreria, ma il
          contrario



16
Template Method
     ✦ Nota
      •   Qualunque passo di un algoritmo può essere
          trasformato in un hook; tuttavia se il numero di
          hook è eccessivo il template method risulta
          difficile da comprendere e da utilizzare
      •   Per questo nella scelta di cosa trasformare in
          hook occorre seguire la raccomandazione YAGNI:
          la decisione va presa in base alle necessità
          presenti, mentre per necessità future si ricorrerà
          al refactoring



17
Chain of Responsibility


     ✦ Il problema
      •   una determinata richiesta potrebbe essere gestita
          da più di un oggetto (Handler), e si vuole
          disaccoppiare il client che genera la richiesta dalla
          conoscenza di quale specifico handler la dovrà
          gestire




18
Chain of Responsibility
     ✦ Esempio del problema
      •   In un programma con una GUI, l’evento
          “pressione di un tasto”, generato dal windowing
          system, potrebbe essere gestito da diversi
          oggetti:
          ‣   il controllo (es. bottone o text field) correntemente
              selezionato
          ‣   il pannello in cui sono inseriti i controlli (es. per la
              navigazione con TAB)
          ‣   la finestra in cui è inserito il pannello (es. per la gestione
              dei menù)
          ‣   il windowing system stesso (es. per cambiare finestra con
              Alt-TAB o attivare il Task Manager con Ctrl-Alt-DEL)


19
Chain of Responsibility
     ✦ Esempio del problema
      •   il programma deve utilizzare alcuni parametri di
          configurazione che ne determinano il
          comportamento:
          ‣   ciascun parametro può essere specificato sulla linea di
              comando
          ‣   se il parametro non è sulla linea di comando, può essere
              letto da un file di configurazione
          ‣   se il parametro non è nemmeno nel file di configurazione,
              si usa un valore di default “cablato” nel programma

      •   le classi che usano questi parametri non
          dovrebbero preoccuparsi di qual è il modo in cui
          l’utente li ha specificati
20
Chain of Responsibility

     ✦ Soluzione
      •   si definisce una classe astratta Handler, i cui
          oggetti hanno un metodo per gestire la richiesta,
          e mantengono un riferimento ad un altro Handler
          (successore)
      •   la richiesta viene inviata a una catena di Handler
          ciascuno dei quali può decidere se gestirla
          direttamente o passarla all’Handler successivo




21
Chain of Responsibility
     ✦ Esempio di struttura




22
Chain of Responsibility
       ✦ Esempio di soluzione



     public abstract class Parameters {
     	 protected Parameters next;
     	 protected Parameters(Parameters next) {
     	 	 this.next = next;
     	 }
     	
     	 public abstract String getParameter(String name);
     }




23
Chain of Responsibility
       ✦ Esempio di soluzione (continua)
     public class CommandLineParameters extends Parameters {
     	 private String args[];
     	 public CommandLineParameters(String args[], Parameters next) {
     	 	 super(next);
     	 	 this.args=args;
     	 }
     	 public String getParameter(String name) {
     	 	 String value=search(name);
     	 	 if (value==null && next!=null)
     	 	 	 value=next.getParameter(name);
     	 	 return value;
     	 }
     	 private String search(String name) {
     	 	 // Search the parameter in the command line
     	 }
     }
24
Chain of Responsibility
       ✦ Esempio di soluzione (continua)

     public class ConfigurationFileParameters extends Parameters {
     	 private String fileName;
     	 public ConfigurationFileParameters(String fileName, Parameters next) {
     	 	 super(next);
     	 	 this.fileName=fileName;
     	 }
     	 public String getParameter(String name) {
     	 	 String value=search(name);
     	 	 if (value==null && next!=null)
     	 	 	 value=next.getParameter(name);
     	 	 return value;
     	 }
     	 private String search(String name) {
     	 	 // Search the parameter in the file
     	 }
     }


25
Chain of Responsibility
       ✦ Esempio di soluzione (continua)
     public class DefaultParameters extends Parameters {
     	 private Map<String, String> map;
     	 public DefaultParameters(Parameters next) {
     	 	 super(next);
     	 	 map=new HashMap<String,String>();
     	 	 map.put("param1", "pluto");
     	 	 map.put("param2", "paperino");
     	 }
     public String getParameter(String name) {
     	 	 String value=map.get(name);
     	 	 if (value==null && next!=null)
     	 	 	 value=next.getParameter(name);
     	 	 return value;
     	 }
     }

26
Chain of Responsibility
        ✦ Esempio di soluzione (continua)

     	 public static void main(String args[]) {
     	 	 Parameters defaultParam=new DefaultParameters(null);
     	 	 Parameters cfgFileParam=new
                        ConfigurationFileParameters("pippo.cfg",
                                                    defaultParam);
     	 	 Parameters cmdLineParam=new CommandLineParameters(args,
                                                         cfgFileParam);
     	 	
     	 	 MyClass x=new MyClass(cmdLineParam);
     	 }




27
Chain of Responsibility
     ✦ Conseguenze
      •   c’è un basso accoppiamento tra il client che
          esegue una richiesta e la classe effettivamente
          usata per gestire la richiesta
      •   ci sono più oggetti che hanno la possibilità di
          gestire una richiesta, e ciascun handler seleziona
          da solo le richieste che è in grado di gestire
      •   è possibile definire una priorità tra gli handler: gli
          handler all’inizio della catena hanno una priorità
          più alta rispetto a quelli alla fine della catena
      •   PROBLEMA: se il numero di handler è elevato,
          overhead per scorrere la catena fino all’handler
          giusto
28
Chain of Responsibilty

     ✦ Esempio
      •   nella versione 1.0 di AWT, gli eventi erano gestiti
          dal metodo handleEvent della classe Component;
          se un componente non voleva/poteva gestire
          l’evento, la richiesta veniva inoltrata al
          componente padre
     ✦ Esempio (non OOP)
      •   il PATH per la ricerca dei comandi nella shell dei
          sistemi Unix-like



29
Chain of responsibility

     ✦ Note
      •   in genere è opportuno assicurarsi che alla fine
          della catena ci sia un handler “catch-all”, che dà
          una risposta a ogni richiesta non evasa dagli
          handler precedenti
      •   la costruzione della catena degli handler può
          essere realizzata usando un Factory Method, o un
          Singleton




30

More Related Content

PDF
Lezione 2: I thread
PDF
Lezione 5: Design Pattern Creazionali
PDF
Lezione 6a: Design Pattern Strutturali
PDF
Lezione 9: Design Pattern Comportamentali
PDF
Lezione 6b: Design Pattern Strutturali
PDF
Lezione 8: Design Pattern Comportamentali
PDF
Lezione 3: Sviluppo in Extreme Programming
PDF
Lezione 4: I tool Ant e Subversion
Lezione 2: I thread
Lezione 5: Design Pattern Creazionali
Lezione 6a: Design Pattern Strutturali
Lezione 9: Design Pattern Comportamentali
Lezione 6b: Design Pattern Strutturali
Lezione 8: Design Pattern Comportamentali
Lezione 3: Sviluppo in Extreme Programming
Lezione 4: I tool Ant e Subversion

What's hot (18)

PDF
Lezione 2: Pianificazione in Extreme Programming
ODP
Design Pattern
PPT
PDF
Design pattern template method
PDF
Corso Java 2 - AVANZATO
PDF
Java OCA teoria 1
PDF
Lezione design patterns 2011 (Peron)
PDF
Lezione 11: Accesso ai RESTful Web Services in Java
PDF
Java OCA teoria 4
PDF
Non solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
PDF
Lezione 6: Remote Method Invocation
PDF
Lezione 10: Web Service in Java (2)
PDF
Corso Javascript
PDF
Corso progettazione
PDF
Introduzione alla programmazione Android - Android@tulug lezione 4
PDF
Programmazione funzionale e Stream in Java
PDF
Closure Visto Da Vicino
PDF
Java Unit Testing - Introduction
Lezione 2: Pianificazione in Extreme Programming
Design Pattern
Design pattern template method
Corso Java 2 - AVANZATO
Java OCA teoria 1
Lezione design patterns 2011 (Peron)
Lezione 11: Accesso ai RESTful Web Services in Java
Java OCA teoria 4
Non solo Django: MVC orientato agli oggetti con Plone e Zope Toolkit
Lezione 6: Remote Method Invocation
Lezione 10: Web Service in Java (2)
Corso Javascript
Corso progettazione
Introduzione alla programmazione Android - Android@tulug lezione 4
Programmazione funzionale e Stream in Java
Closure Visto Da Vicino
Java Unit Testing - Introduction
Ad

Similar to Lezione 7: Design Pattern Comportamentali (20)

PDF
pattern
PDF
Introduzione a JavaScript
PPTX
Dal C a Java (1/3)
PDF
Corso Object Oriented Analysis and Design
PPT
Introduzione al Test Driven Development
PPTX
La metodologia Top - Down - applicazione al C++
PDF
Unit Testing
PDF
09 - Programmazione: Ingegneria del Codice
PDF
Hexagonal architecture ita
PDF
Presentazione corretta algoritmi
PPTX
Corso pratico di C# - 2013
ODP
Programmazione Top Down in C++
PDF
C# e la Framework Class Library
PPTX
Coding, pattern e pensiero computazionale
PPTX
PowerMock TDD User Group Milano
PDF
Il testing con zend framework
PDF
Il testing con zend framework
PPT
A static Analyzer for Finding Dynamic Programming Errors
PDF
Elaborazione automatica dei dati: computer e matlab
PDF
Programmazione in C (corso 12BHD Informatica)
pattern
Introduzione a JavaScript
Dal C a Java (1/3)
Corso Object Oriented Analysis and Design
Introduzione al Test Driven Development
La metodologia Top - Down - applicazione al C++
Unit Testing
09 - Programmazione: Ingegneria del Codice
Hexagonal architecture ita
Presentazione corretta algoritmi
Corso pratico di C# - 2013
Programmazione Top Down in C++
C# e la Framework Class Library
Coding, pattern e pensiero computazionale
PowerMock TDD User Group Milano
Il testing con zend framework
Il testing con zend framework
A static Analyzer for Finding Dynamic Programming Errors
Elaborazione automatica dei dati: computer e matlab
Programmazione in C (corso 12BHD Informatica)
Ad

More from Andrea Della Corte (11)

PDF
Lezione 1: I metodi agili
PDF
Lezione 5: Socket SSL/ TLS
PDF
Lezione 9: Web Service in Java
PDF
Lezione 8: Introduzione ai Web Service
PDF
Lezione 7: Remote Method Invocation e SSL
PDF
Lezione12: Autenticazione e gestione delle sessioni in REST
PDF
Lezione 1: I/O in Java
PDF
Lezione 3: Connessioni TCP
PDF
Lezione 4: Comunicazione con UDP
PPT
Tutorial Matlab 2009
PPT
Introduzione ai CRM
Lezione 1: I metodi agili
Lezione 5: Socket SSL/ TLS
Lezione 9: Web Service in Java
Lezione 8: Introduzione ai Web Service
Lezione 7: Remote Method Invocation e SSL
Lezione12: Autenticazione e gestione delle sessioni in REST
Lezione 1: I/O in Java
Lezione 3: Connessioni TCP
Lezione 4: Comunicazione con UDP
Tutorial Matlab 2009
Introduzione ai CRM

Lezione 7: Design Pattern Comportamentali

  • 1. Lezione 23: Design Pattern Comportamentali Corso di Ingegneria del Software Laurea Magistrale in Ing. Informatica Università degli Studi di Salerno 1
  • 2. Outline ✦ Design Pattern Comportamentali • Template Method • Chain of Responsibility 2
  • 4. Design Pattern Comportamentali ✦ Lo scopo comune è affrontare problemi che riguardano il modo in cui un oggetto svolge la sua funzione, o il modo in cui un insieme di oggetti collaborano per svolgere un determinato compito 4
  • 5. Template Method ✦ Il problema • Spesso capita di incontrare diversi problemi che si risolvono con algoritmi che hanno la stessa struttura, ma differiscono in alcune operazioni di dettaglio ‣ ripetere più volte la struttura comune è una violazione del principio DRY ‣ si vuole avere la possibilità di riutilizzare la struttura comune per reimplementare più semplicemente nuovi algoritmi dello stesso tipo 5
  • 6. Template Method ✦ Esempio del problema public int computeSum(int a[], int n) { int sum=0; int i; for(i=0; i<n; i++) sum=sum+a[i]; return sum; } public int computeProduct(int a[], int n) { int product=1; int i; for(i=0; i<n; i++) product=product*a[i]; return product; } 6
  • 7. Template Method ✦ Esempio del problema • la struttura comune: public int computeXxx(int a[], int n) { int valore=”valore iniziale”; int i; for(i=0; i<n; i++) valore=”combinazione di valore e a[i]” return valore; } 7
  • 8. Template Method ✦ Soluzione • si definisce una classe “abstract” per lo schema di algoritmo • la struttura dell’algoritmo è definita in un metodo (“template method”), che richiama altri metodi (“hook methods”) per le parti che differiscono tra i vari problemi • gli hook methods possono avere una implementazione di default, o essere metodi “abstract” • per ogni problema concreto si crea una sottoclasse che implementa i metodi hook 8
  • 9. Template Method ✦ Esempio di struttura 9
  • 10. Template Method ✦ Esempio di soluzione public abstract class Accumulator { // Template method public int compute(int a[], int n) { int value=initialValue(); int i; for(i=0; i<n; i++) value=combine(value, a[i]); return value; } // Hook method public abstract int initialValue(); // Hook method public abstract int combine(int currentValue, int element); } 10
  • 11. Template Method ✦ Esempio di soluzione (continua) public class SumAccumulator extends Accumulator { public int initialValue() { return 0; } public int combine(int currentValue, int element) { return currentValue+element; } } 11
  • 12. Template Method ✦ Esempio di soluzione (continua) public class ProductAccumulator extends Accumulator { public int initialValue() { return 1; } public int combine(int currentValue, int element) { return currentValue*element; } } 12
  • 13. Template Method ✦ Esempio di soluzione (continua) public class CountPositiveAccumulator extends Accumulator { public int initialValue() { return 0; } public int combine(int currentValue, int element) { if (element>0) return currentValue+1; else return currentValue; } } 13
  • 14. Template Method ✦ Conseguenze • si separa la struttura generale comune a un insieme di algoritmi dai dettagli che differiscono, consentendo il riuso della prima • si garantisce la coerenza tra le soluzioni a problemi analoghi • è possibile applicare la stessa struttura a problemi nuovi, inizialmente non considerati 14
  • 15. Template Method ✦ Esempi • numerosi framework utilizzano questo pattern per definire applicazioni in cui la struttura generale dell’applicazione è fissata, e lo sviluppatore deve specificare soltanto gli elementi peculiari dell’applicazione corrente ‣ Applet ‣ Servlet 15
  • 16. Template Method ✦ Nota • questo pattern rappresenta un esempio di applicazione del cosiddetto “Hollywood Principle”, così denominato dalla “risposta standard” nei provini di dilettanti a Hollywood: “Don’t call us...We’ll call you.” • l’idea di base di questo principio è che non è il codice specifico dell’applicazione a richiamare il codice generale presente in una libreria, ma il contrario 16
  • 17. Template Method ✦ Nota • Qualunque passo di un algoritmo può essere trasformato in un hook; tuttavia se il numero di hook è eccessivo il template method risulta difficile da comprendere e da utilizzare • Per questo nella scelta di cosa trasformare in hook occorre seguire la raccomandazione YAGNI: la decisione va presa in base alle necessità presenti, mentre per necessità future si ricorrerà al refactoring 17
  • 18. Chain of Responsibility ✦ Il problema • una determinata richiesta potrebbe essere gestita da più di un oggetto (Handler), e si vuole disaccoppiare il client che genera la richiesta dalla conoscenza di quale specifico handler la dovrà gestire 18
  • 19. Chain of Responsibility ✦ Esempio del problema • In un programma con una GUI, l’evento “pressione di un tasto”, generato dal windowing system, potrebbe essere gestito da diversi oggetti: ‣ il controllo (es. bottone o text field) correntemente selezionato ‣ il pannello in cui sono inseriti i controlli (es. per la navigazione con TAB) ‣ la finestra in cui è inserito il pannello (es. per la gestione dei menù) ‣ il windowing system stesso (es. per cambiare finestra con Alt-TAB o attivare il Task Manager con Ctrl-Alt-DEL) 19
  • 20. Chain of Responsibility ✦ Esempio del problema • il programma deve utilizzare alcuni parametri di configurazione che ne determinano il comportamento: ‣ ciascun parametro può essere specificato sulla linea di comando ‣ se il parametro non è sulla linea di comando, può essere letto da un file di configurazione ‣ se il parametro non è nemmeno nel file di configurazione, si usa un valore di default “cablato” nel programma • le classi che usano questi parametri non dovrebbero preoccuparsi di qual è il modo in cui l’utente li ha specificati 20
  • 21. Chain of Responsibility ✦ Soluzione • si definisce una classe astratta Handler, i cui oggetti hanno un metodo per gestire la richiesta, e mantengono un riferimento ad un altro Handler (successore) • la richiesta viene inviata a una catena di Handler ciascuno dei quali può decidere se gestirla direttamente o passarla all’Handler successivo 21
  • 22. Chain of Responsibility ✦ Esempio di struttura 22
  • 23. Chain of Responsibility ✦ Esempio di soluzione public abstract class Parameters { protected Parameters next; protected Parameters(Parameters next) { this.next = next; } public abstract String getParameter(String name); } 23
  • 24. Chain of Responsibility ✦ Esempio di soluzione (continua) public class CommandLineParameters extends Parameters { private String args[]; public CommandLineParameters(String args[], Parameters next) { super(next); this.args=args; } public String getParameter(String name) { String value=search(name); if (value==null && next!=null) value=next.getParameter(name); return value; } private String search(String name) { // Search the parameter in the command line } } 24
  • 25. Chain of Responsibility ✦ Esempio di soluzione (continua) public class ConfigurationFileParameters extends Parameters { private String fileName; public ConfigurationFileParameters(String fileName, Parameters next) { super(next); this.fileName=fileName; } public String getParameter(String name) { String value=search(name); if (value==null && next!=null) value=next.getParameter(name); return value; } private String search(String name) { // Search the parameter in the file } } 25
  • 26. Chain of Responsibility ✦ Esempio di soluzione (continua) public class DefaultParameters extends Parameters { private Map<String, String> map; public DefaultParameters(Parameters next) { super(next); map=new HashMap<String,String>(); map.put("param1", "pluto"); map.put("param2", "paperino"); } public String getParameter(String name) { String value=map.get(name); if (value==null && next!=null) value=next.getParameter(name); return value; } } 26
  • 27. Chain of Responsibility ✦ Esempio di soluzione (continua) public static void main(String args[]) { Parameters defaultParam=new DefaultParameters(null); Parameters cfgFileParam=new ConfigurationFileParameters("pippo.cfg", defaultParam); Parameters cmdLineParam=new CommandLineParameters(args, cfgFileParam); MyClass x=new MyClass(cmdLineParam); } 27
  • 28. Chain of Responsibility ✦ Conseguenze • c’è un basso accoppiamento tra il client che esegue una richiesta e la classe effettivamente usata per gestire la richiesta • ci sono più oggetti che hanno la possibilità di gestire una richiesta, e ciascun handler seleziona da solo le richieste che è in grado di gestire • è possibile definire una priorità tra gli handler: gli handler all’inizio della catena hanno una priorità più alta rispetto a quelli alla fine della catena • PROBLEMA: se il numero di handler è elevato, overhead per scorrere la catena fino all’handler giusto 28
  • 29. Chain of Responsibilty ✦ Esempio • nella versione 1.0 di AWT, gli eventi erano gestiti dal metodo handleEvent della classe Component; se un componente non voleva/poteva gestire l’evento, la richiesta veniva inoltrata al componente padre ✦ Esempio (non OOP) • il PATH per la ricerca dei comandi nella shell dei sistemi Unix-like 29
  • 30. Chain of responsibility ✦ Note • in genere è opportuno assicurarsi che alla fine della catena ci sia un handler “catch-all”, che dà una risposta a ogni richiesta non evasa dagli handler precedenti • la costruzione della catena degli handler può essere realizzata usando un Factory Method, o un Singleton 30