Lezione 7: Design Pattern Comportamentali

  • 1,381 views
Uploaded on

✦ Design Pattern Comportamentali …

✦ Design Pattern Comportamentali
• Template Method
• Chain of Responsibility

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,381
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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
  • 3. Design Pattern Comportamentali 3
  • 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