95
1 Design Patterns Uniroma2 - Arch. e Servizi SW per Internet

Design Patterns - Università degli Studi di Roma "Tor Vergata" · Classificazione completa Scopo Creazionale Strutturale Comportamentale Factory Method Adapter (class) Interpreter

Embed Size (px)

Citation preview

1

Design Patterns

Uniroma2 - Arch. e Servizi SW per Internet!

2

Introduzione w  La progettazione di software orientato ad

oggetti è una attività complessa w  Una delle maggiori difficoltà che il

progettista deve affrontare è l’individuazione di un insieme di oggetti: •  correttamente individuato •  il più possibile riusabile •  definendo al meglio le relazioni tra classi e le

gerarchie di ereditarietà

Uniroma2 - Arch. e Servizi SW per Internet!

3

Una lezione da imparare “Ogni pattern descrive un problema che si ripete più e più volte nel nostro ambiente, descrive poi il nucleo della soluzione del problema, in modo tale che si possa riusare la soluzione un milione di volte, senza mai applicarla alla stessa maniera.” Christopher Alexander

- Architetto -

Uniroma2 - Arch. e Servizi SW per Internet!

4

Desing Pattern: Alcune Caratteristiche

w  Rappresentano soluzioni a problematiche ricorrenti che si incontrano durante le varie fasi di sviluppo del software.

w  Organizzano l’esperienza di OOD favorendo il riuso.

w  Evitano al progettista di reinventare ogni volta la ruota

w  Permettono di imparare dal lavoro degli altri (evitando errori comuni…)

Uniroma2 - Arch. e Servizi SW per Internet!

5

Desing Pattern: Alcune Caratteristiche (2)

w  Permettono di definire un linguaggio comune che semplifica la comunicazione tra gli addetti ai lavori.

w  Indirizzano verso la scrittura di codice che usa strutture valide.

w  Portano di norma ad una buona progettazione: semplificano la manutenzione (adattiva, perfettiva, preventiva e correttiva).

w  Non risolvono tutti i problemi! Uniroma2 - Arch. e Servizi SW per Internet!

6

Riferimenti Bibliografici w  E. Gamma, R. Helm, R. Johnson, J.

Vlissides (GoF, Gang of Four), Design Patterns – Elementi per il riuso di software a oggetti, Addison Wesley

w  Craig Larman Applicare UML e i Pattern, Prentice Hall

Uniroma2 - Arch. e Servizi SW per Internet!

7

Classificazione w  Un primo criterio riguarda lo scopo

(purpose). •  Creazionali: i pattern di questo tipo sono relativi

alle operazioni di creazione di oggetti. •  Strutturali: sono utilizzati per definire la

struttura del sistema in termini della composizione di classi ed oggetti. Si basano sui concetti OO di ereditarietà e polimorfismo.

•  Comportamentali:permettono di modellare le il comportamento del sistema definendo le responsabilità delle sue componenti e definendo le modalità di interazione.

Uniroma2 - Arch. e Servizi SW per Internet!

8

Classificazione (2) w  Un secondo criterio riguarda il raggio di

azione (scope): •  Classi: pattern che definiscono le relazioni fra

classi e sottoclassi. Le relazioni sono basate prevalentemente sul concetti di ereditarietà e sono quindi statiche (definite a tempo di compilazione).

•  Oggetti: pattern che definiscono relazioni tra oggetti, che possono cambiare durante l’esecuzione e sono quindi più dinamiche.

Uniroma2 - Arch. e Servizi SW per Internet!

9

Catalogo dei Pattern (GoF) 1. Adapter 2. Façade 3. Composite 4. Decorator 5. Bridge 6. Singleton 7. Proxy 8. Flyweight 9. Strategy 10. State 11. Command 12. Observer

13. Memento 14. Interpreter 15. Iterator 16. Visitor 17. Mediator 18. Template Method 19. Chain of Responsibility 20. Builder 21. Prototype 22. Factory Method 23. Abstract Factory

Uniroma2 - Arch. e Servizi SW per Internet!

10

Classificazione completa Scopo

Creazionale Strutturale Comportamentale

Factory Method Adapter (class) Interpreter Template Method

Abstract Factory Builder Prototype Singleton

Adapter (object) Bridge Composite Decorator Facade Flyweight Proxy

Chain of responsability Iterator Mediator Memento Observer State Strategy Visitor

Ragg

io d

’azi

one

Cla

ssi

Ogg

etti

Uniroma2 - Arch. e Servizi SW per Internet!

11

Descrizione dei Design Pattern w  Nome e Classificazione: il nome illustra l’essenza

di un pattern definendo un vocabolario condiviso tra i progettisti; la classificazione lo identifica in termini di scopo e raggio di azione.

w  Motivazione: scenario che descrive in modo astratto il problema al quale applicare il pattern; può includere la la lista eventuali pre-condizioni necessarie a garantirne l’applicabilità.

w  Applicabilità: Descrive le situazioni in cui il pattern può essere applicato.

w  Struttura:descrive graficamente la configurazione di elementi che risolvono il problema (relazioni, responsabilità, collaborazioni).

E’ uno schema di soluzione, non una soluzione per un progetto specifico

Uniroma2 - Arch. e Servizi SW per Internet!

12

Descrizione dei Design Pattern(2) w  Partecipanti: classi ed oggetti che fanno parte del

pattern con le relative responsabilità. w  Conseguenze: risultati che si ottengono applicando

il pattern. w  Implementazioni: tecniche e suggerimenti utili

all’implementazione del pattern.

w  Codice di esempio: frammenti di codice che illustrano come implementare in un certo linguaggio di programmazione (es. java o c++) il pattern.

w Usi conosciuti: esempi di applicazione in sistemi reali

w  Pattern correlati: altri pattern correlati Uniroma2 - Arch. e Servizi SW per Internet!

13

Un concetto utile: i Framework w  Un Framework non è una semplice libreria.

w  Un Framework rappresenta il design riusabile di un sistema (o di una sua parte), definito da un insieme di classi astratte.

w  Un framework è lo scheletro di un’applicazione che viene personalizzato (customized) da uno sviluppatore

w  Il programmatore di applicazioni implementa le interfacce e classi astratte ed ottiene automaticamente la gestione delle funzionalità richieste.

Uniroma2 - Arch. e Servizi SW per Internet!

14

I Framework (2) w  I Framework permettono quindi di definire

lo scopo e la struttura statica di un sistema. w  Sono un buon esempio di progettazione

orientata agli oggetti. w  Permettono di raggiungere due obiettivi:

•  Il riuso del design •  Il riuso del codice

Uniroma2 - Arch. e Servizi SW per Internet!

15

I Framework (3) w  Classe Astratta: una classe astratta è una

classe che possiede almeno un metodo non implementato, definito “astratto”.

w  Una classe astratta è quindi un template per le sottoclassi da cui deriveranno le specifiche applicazioni.

w  Un framework è rappresentato da un’insieme di classi astratte e dalle loro interrelazioni.

w  I Pattern sono spesso mattoni per la costruzione di framework.

Uniroma2 - Arch. e Servizi SW per Internet!

16

Abstract Factory w  Scopo: fornire una interfaccia per la

creazione di famiglie di oggetti tra loro correlati

w Motivazione: realizzazione di uno strumento per lo sviluppo di user interface (UI) in grado di supportare diversi tipi di look & feel. Per garantire la portabilità di una applicazione tra look & feel diversi, gli oggetti non devono essere cablati nel codice.

Classificazione: creazionale basato su oggetti Uniroma2 - Arch. e Servizi SW per Internet!

17

Abstract Factory: esempio w  Consideriamo uno strumento per realizzare UI con

due soli elementi, in grado di supportare due look & feel diversi •  Look&Feel1 -> Window1 e ScrollBar1 •  Look&Feel2 -> Window2 e ScrollBar2

w  L’applicazione client deve realizzare una UI che rispetti le relazioni tra gli oggetti e che sia portabile da un L&F ad un altro: •  Il client non dovrebbe istanziare direttamente gli oggetti •  Bisogna evitare che il client accoppi (sbagliando) Window1

e ScrollBar2

w  Usiamo una Abstract Factory Uniroma2 - Arch. e Servizi SW per Internet!

18

Abstract Factory: esempio (2)

Client

Window1 Window2 ScrollBar1 ScrollBar2

<<istantiates>> <<istantiates>>

createWindow() createScollBar()

Factory

createWindow() createScollBar()

Factory1

createWindow() createScollBar()

Factory2

Window ScrollBar

Uniroma2 - Arch. e Servizi SW per Internet!

19

Abstract Factory: esempio (3)

Factory f = new Factory1(); Window w = f.createWindow(); ... ScrollBar s = f.createScrollBar();

Window w = new Window1(); ... ScrollBar s = new ScrollBar1();

w  Senza utilizzare l’Abstract Factory l’applicazione client deve esplicitamente istanziare gli oggetti.

w  Il rispetto delle relazioni è cablato nel codice e deve essere noto al client.

w  Con l’Abstract Factory la responsabilità è demandata alla Factory.

Uniroma2 - Arch. e Servizi SW per Internet!

20

Abstract Factory: struttura

Client

ProductB1 ProductB2

<<istantiates>> <<istantiates>>

createProductA() createProductB()

AbstractFactory

createProductA() createProductB()

ConcreteFactory1

createProductA() createProductB()

ConcreteFactory2

AbstractProductA

AbstractProductB

ProductA1 ProductA2

Uniroma2 - Arch. e Servizi SW per Internet!

21

Altre caratteristiche w  Applicabilità

•  Un sistema deve essere indipendente dalle modalità di creazione dei prodotti con cui opera

•  Un sistema deve poter essere configurato per usare famiglie di prodotti diverse

•  Il client non deve essere legato ad una specifica famiglia

w  Partecipanti •  AbstractFactory e ConcreteFactory •  AbstractProduct e ConcreteProduct •  Applicazione Client

Uniroma2 - Arch. e Servizi SW per Internet!

22

Altre caratteristiche (2) w  Conseguenze

•  Le classi concrete sono isolate e sotto controllo. •  La famiglia di prodotti può essere cambiata

rapidamente perché la factory completa compare in un unico punto del codice.

•  Aggiungere nuove famiglie di prodotti è difficile perché l’insieme di prodotti gestiti è legato all’interfaccia della factory.

Uniroma2 - Arch. e Servizi SW per Internet!

23

Factory Method w  Scopo: Definire una interfaccia per la

creazione di un oggetto, che consenta di decidere a tempo di esecuzione quale specifico oggetto istanziare.

w Motivazione: E’ un pattern ampiamente usato nei framework, dove le classi astratte definiscono le relazioni tra gli elementi del dominio, e sono responsabili per la creazione degli oggetti concreti.

Classificazione: creazionale basato su classi

Uniroma2 - Arch. e Servizi SW per Internet!

24

Factory Method: esempio w  Consideriamo un framework di gestione di

documenti di tipo diverso. w  Le due astrazioni chiave sono Application e

Document. w  Gli utilizzatori devono definire delle sotto

classi per ottenere delle implementazioni adatte all’applicazione specifica.

w  Application contiene la logica per sapere quando un nuovo documento sarà creato, ma non per sapere quale tipo di documento creare.

Uniroma2 - Arch. e Servizi SW per Internet!

25

Factory Method: esempio (2) w  Il pattern Factory incapsula la conoscenza

della specifica classe da creare al di fuori del framework

createDocument() openDocument()

Application

open() close()

Document

open() close()

PDFDocument

createDocument()

MyApplication

Document doc = createDocument doc.open()

return new PDFDocument()

Uniroma2 - Arch. e Servizi SW per Internet!

26

Factory Method: struttura

factoryMethod() anOperation()

Creator

Product

ConcreteProduct

createDocument()

MyApplication

product = factoryMethod()

return new concreteProduct()

Uniroma2 - Arch. e Servizi SW per Internet!

27

Altre caratteristiche w  Applicabilità

•  Una classe non è in grado di sapere in anticipo le classi di oggetti che deve creare.

•  Una classe vuole che le sue sottoclassi scelgano gli oggetti da creare.

•  Le classi delegano la responsabilità di creazione. w  Partecipanti

•  Product e ConcreteProduct •  Creator e ConcreteCreator

w  Conseguenze •  Elimina la necessità di riferirsi a classi dipendenti

dall’applicazione all’interno del codice.

Uniroma2 - Arch. e Servizi SW per Internet!

28

Adapter w  Scopo: Convertire l’interfaccia di una

classe esistente incompatibile con un client, in una compatibile.

w Motivazione: Consideriamo un editor che consente di disegnare e comporre elementi grafici. L’astrazione chiave è un singolo oggetto grafico. Supponiamo di voler integrare un nuovo componente, ma che questo non abbia una interfaccia compatibile con l’editor.

Classificazione: strutturale basato su classi/oggetti

Uniroma2 - Arch. e Servizi SW per Internet!

29

Adapter: esempio w  Supponiamo di voler integrare il componente

Circle nell’editor che già supporta le forme Triangle e Rectangle.

getPosition() setPosition() Display()

Shape

Display()

Rectangle

Display()

Triangle

Show()

Circle

Uniroma2 - Arch. e Servizi SW per Internet!

30

Adapter: esempio (2) w  Soluzione 1: Object Adapter

getPosition() setPosition() Display()

Shape

Display()

Rectangle

Display()

Triangle

Show()

Circle

Display()

CircleAdapter

Uniroma2 - Arch. e Servizi SW per Internet!

31

Adapter: esempio (3) w  Soluzione 1: Class Adapter

getPosition() setPosition() Display()

Shape

Display()

Rectangle

Display()

Triangle

Show()

Circle

Display()

CircleAdapter

Uniroma2 - Arch. e Servizi SW per Internet!

32

Adapter: struttura

request()

Target

request()

Adapter

specificRequest()

Adaptee Client

specificRequest()

request()

Target

request()

Adapter

specificRequest()

Adaptee Client

Adaptee.specificRequest()

Class Adapter

Object Adapter

Uniroma2 - Arch. e Servizi SW per Internet!

33

Altre caratteristiche w  Applicabilità

•  Si usa quando si vuole riusare una classe esistente, ma con interfaccia incompatibile con quella desiderata.

w  Partecipanti •  Client •  Target •  Adapter ed Adaptee

w  Conseguenze: E’ necessario prendere in considerazione l’effort necessario all’adattamento

Uniroma2 - Arch. e Servizi SW per Internet!

34

Composite w  Scopo: Comporre oggetti in strutture che

consentano di trattare i singoli elementi e la composizione in modo uniforme.

w Motivazione: Le applicazioni grafiche consentono di trattare in modo uniforme sia le forme geometriche di base (linee, cerchi,…) sia gli oggetti complessi che si creano a partire da questi elementi semplici. Molti editor grafici ad esempio hanno la funzione raggruppa Classificazione: strutturale basato su oggetti

Uniroma2 - Arch. e Servizi SW per Internet!

35

Composite: esempio w  Consideriamo un applicazione grafica in

grado di gestire gli oggetti elementari Triangle, Rectangle, e Circle.

w  Un ulteriore requisito è che l’applicazione deve poter permettere il raggruppamento dinamico di oggetti elementari in oggetti compositi.

w  Gli oggetti elementari e quelli compositi devono essere trattati in modo uniforme

Uniroma2 - Arch. e Servizi SW per Internet!

36

Composite: esempio (2)

getPosition() setPosition() display() add(Shape s)

Shape

display()

Rectangle

display()

Triangle

show() add(Shape s)

CompositeFigure

display()

Circle

Client 1 *

1

*

w  La sola relazione di composizione non soddisfa tutti i requisiti: CompositeFigure è una collezione di oggetti elementari ma non è essa stessa una figura geometrica (Shape)

La relazione di ereditarietà permette di considerare CompositeFigure una figura geometrica

Uniroma2 - Arch. e Servizi SW per Internet!

37

Composite: struttura

operation() add(Component) remove(Component c)

Component

operation()

Leaf

Operation() add(Component c) remove(Component c)

Composite

Client

children

Uniroma2 - Arch. e Servizi SW per Internet!

38

Altre Caratteristiche w  Applicabilità

•  Si usa quando si vogliono rappresentare gerarchie di oggetti in modo che oggetti semplici e oggetti compositi siano trattati in modo uniforme.

w  Partecipanti •  Component e Coposite •  Leaf •  Client

Uniroma2 - Arch. e Servizi SW per Internet!

39

Altre Caratteristiche (2) w  Conseguenze

•  I client sono semplificati perché gli oggetti semplici e quelli compositi sono trattati allo stesso modo.

•  L’aggiunta di nuovi oggetti Leaf o Composite è semplice, e questi potranno sfruttare il codice dell’applicazione Client già esistente.

•  Può rendere il sistema troppo generico. Non è possibile fare in modo che un oggetto composito contenga solo un certo tipo di oggetti.

Uniroma2 - Arch. e Servizi SW per Internet!

40

Decorator w  Scopo: Aggiungere dinamicamente

funzionalità (responsabilità) ad un oggetto. w Motivazione: Uno scenario classico di

applicabilità per questo pattern è la realizzazione di interfacce utente. Responsabilità quali il testo scorrevole o un particolare bordo devono poter essere aggiunti a livello di singolo oggetto.

Il subclassing è una alternativa statica e il cui scope è a livello di classe e non di singolo oggetto.

Classificazione: strutturale basato su oggetti Uniroma2 - Arch. e Servizi SW per Internet!

41

Decorator: esempio

Come combinare i tre oggetti aBorderDecorator, aScrollDecorator e aTextView per raggiungere l’obiettivo della dinamicità?

Uniroma2 - Arch. e Servizi SW per Internet!

42

Decorator: esempio (2) Il primo approccio che scartiamo è quello del subclassing.

TextView

BorderTextView ScrollTextView

w  E’ un approccio statico. Una volta creato BorderTextView non posso più cambiarlo.

w  Devo creare una sottoclasse per ogni esigenza

w  E per creare una finestra che abbia sia il bordo, sia il testo scorrevole?

•  BorderAndScrollTextView? •  ScrollAndBorderTextView?

Uniroma2 - Arch. e Servizi SW per Internet!

43

Decorator: esempio (3) w  Un approccio più flessibile è quello di

racchiudere un oggetto elementare in un altro, che aggiunge una responsabilità particolare.

w  L’oggetto contenitore è chiamato Decorator. w  Il Decorator ha una interfaccia conforme

all’oggetto da decorare. w  Il Decorator trasferisce le richieste

all’oggetto decorato ma può svolgere funzioni aggiuntive (ad esempio aggiungere un bordo) prima o dopo il trasferimento della richiesta.

Uniroma2 - Arch. e Servizi SW per Internet!

44

Decorator: esempio (4)

draw()

TextView

draw() Scroll()

ScrollDecorator

draw() borderDraw()

BorderDecorator

draw()

<<interface>> UIComponent

{ super.draw(); borderDraw(); }

Il metodo draw() del decoratore esegue prima il metodo dell’oggetto elementare, e poi invoca il suo metodo (privato) borderDraw() per aggiungere un comportamento specifico

Area di testo con bordo e barre di scorrimento: t = new BorderDecorator( new ScrollDecorator (new TextView()));

draw()

Decorator

UIComponent c { c.draw(); }

Uniroma2 - Arch. e Servizi SW per Internet!

45

Decorator: struttura

operation()

ConcreteComponent

operation()

Decorator

addedState operation()

ConcreteDecoratorA

operation() addedOperation()

ConcreteDecoratorB

operation()

<<interface>> Component

Uniroma2 - Arch. e Servizi SW per Internet!

46

Altre caratteristiche w  Applicabilità

•  Si applica quando è necessario aggiungere responsabilità agli oggetti in modo trasparente e dinamico.

•  Si applica quando il subclassing non è adatto. w  Partecipanti

•  Component e ConcreteComponent •  Decorator e ConcreteDecorator(s)

w  Conseguenze: •  Maggiore flessibilità rispetto all’approccio statico •  Evita di definire stutture gerarchiche complesse

Uniroma2 - Arch. e Servizi SW per Internet!

47

Decorator: alcune note w  In Java il Decorator è particolarmente

usato nella definizione degli Stream di I/O:

w  E’ simile al pattern Composite, ma la finalità è diversa. Decorator serve ad aggiungere reponsabilità in modo dinamico.

w  E’ simile al pattern Adapter, ma quest’ultimo si limita ad un adattamento (limitato) di una interfaccia.

BufferedInputStream bin = new BufferedInputStream( new FileInputStream( "test.dat"));

Uniroma2 - Arch. e Servizi SW per Internet!

48

Observer w  Scopo: Definire una dipendenza uno a

molti tra oggetti, mantenendo basso il grado di coupling. In altre parole la variazione dello stato di un oggetto deve essere osservata da altri oggetti, in modo che possano aggiornarsi automaticamente.

w Motivazione: Lo scenario classico è quello di applicazioni con GUI, realizzate secondo il paradigma Model-View-Control. Quando il Model cambia, gli oggetti che implementano la View devono aggiornarsi Classificazione: comportamentale basato su oggetti

Uniroma2 - Arch. e Servizi SW per Internet!

49

Observer: l’idea di fondo

Oggetto Controllato Variazione di stato

Osservatore 1 Osservatore 2

Uniroma2 - Arch. e Servizi SW per Internet!

50

Observer: una possibile soluzione w  Una prima soluzione potrebbe essere quella

di utilizzare, nell’oggetto osservato, attributi pubblici oppure metodi pubblici che leggono il valore di una attributo protetto.

w  Non è una buona soluzione: •  Non è scalabile: se aumentano troppo gli

osservatori l’oggetto osservato è sovraccaricato dalle richieste.

•  Gli osservatori dovrebbero continuamente interrogare l’oggetto osservato.

•  Variazioni rapide potrebbero comunque non essere rilevate da qualche osservatore.

Uniroma2 - Arch. e Servizi SW per Internet!

51

Observer: l’approccio corretto w  Il pattern Observer prevede che gli

osservatori si registrino presso l’oggetto osservato.

w  In questo modo è l’oggetto osservato che notifica ogni cambiamento di stato agli osservatori.

w  Quando l’osservatore rileva la notifica può interrogare l’oggetto osservato, oppure può svolgere altre operazioni indipendenti dal valore specifico dello stato.

Uniroma2 - Arch. e Servizi SW per Internet!

52

Observer: l’approccio corretto (2) w  L’oggetto osservato non conosce l’identità

degli osservatori. w  Gli osservatori possono essere aggiunti al

runtime.

Oggetto Controllato

Variazione di stato

Ossevatore 1 Osservatore 2

notifiche interrogazione

Uniroma2 - Arch. e Servizi SW per Internet!

53

Observer: struttura

register() remove() notify()

Subject

state setState() getState()

ConcreteSubject

update()

Observer

observerState update()

ConcreteObserver

0..*

1

{ for all observer o o.update() }

{ observerState= Subject.getState() }

Uniroma2 - Arch. e Servizi SW per Internet!

54

Observer: sequence diagram AnyObject s:ConcreteSubject o1:ConcreteObserver o2:ConcreteObserver

setState( ) notify( )

update( )

update( )

getState( )

register( )

register( )

getState( )

Uniroma2 - Arch. e Servizi SW per Internet!

55

Altre caratteristiche w  Applicabilità

•  Si applica quando una azione può essere scomposta in due ambiti, ciascuno dei quali incapsulato in oggetti separati per mantenere basso il livello di coupling.

•  Gestire le modifiche di oggetti conseguenti alla variazione dello stato di un oggetto.

w  Partecipanti •  Subject e ConcreteSubject •  Observer e ConcreteObserver

Uniroma2 - Arch. e Servizi SW per Internet!

56

Altre caratteristiche (2) w  Conseguenze

•  L’accoppiamento tra Subject ed Observer è astratto: i Subject conoscono solo la lista degli osservatori.

•  La notifica è una comunicazione di tipo broadcast: il soggetto non si occupa di quanto sono gli observer registrati.

•  Attenzione perché una modifica al Subject scatena una serie di modifiche a tutti gli osservatori e su tutti gli oggetti da questi dipendenti.

Uniroma2 - Arch. e Servizi SW per Internet!

57

Template Method w  Scopo: Definire la struttura di un algoritmo

all’interno di un metodo, delegando alcuni passi alle sottoclassi.

w Motivazione: consideriamo un framework per costruire applicazioni in grado di gestire documenti diversi. Il Template Method definisce un algoritmo in base ad operazioni astratte che saranno definite nelle sottoclassi specifiche.

Le sottoclassi ridefiniscono solo alcuni passi dell’algoritmo ma non la sua struttura.

Classificazione: comportamentale basato su classi Uniroma2 - Arch. e Servizi SW per Internet!

58

Template Method: esempio w  Consideriamo quindi un semplice framework

costituito da 2 classi: Application e Document.

create() canOpen()

ConcreteSubject

OpenDocument() create() canOpen()

Application

save() open() close() read()

Document

read()

ConcreteDocument

OpenDocument {

if(!canOpen()){ //errormessage } create()

}

Uniroma2 - Arch. e Servizi SW per Internet!

59

Template Method: struttura

primitiveOperation1() primitiveOperation2()

ConcreteClass()

Client templateMethod() primitiveOperation1() primitiveOperation2()

AbstractClass

templateMethod() { … primitiveOperation1(); primitiveOperation2(); … }

Uniroma2 - Arch. e Servizi SW per Internet!

60

Altre caratteristiche w  Applicabilità

•  E’ utilizzato per implementare la parte invariante di un algoritmo, lasciando alle sottoclassi la definizione degli step variabili.

•  E’ utile quando ci sono comportamenti comuni che possono essere inseriti nel template.

w  Partecipanti •  AbstractClass e ConcreteClass •  Client

Uniroma2 - Arch. e Servizi SW per Internet!

61

Altre caratteristiche w  Conseguenze

•  I metodi template permettono il riuso del codice •  Creano una struttura di controllo invertito dove

è la classe padre che chiama le operazioni ridefinite nei figli e non viceversa

•  Per controllare l’estendibilità delle sottoclassi, i metodi richiamati dal template sono chiamati metodi gancio (hook)

•  I metodi hook possono essere implementati, offrendo un comportamento standard, che la sottoclasse può volendo ridefinire.

Uniroma2 - Arch. e Servizi SW per Internet!

62

Alcune note w  Il Template Method è simile al Factory Method.

•  Invocazione di metodi astratti tramite interfaccia •  Implementazione dei metodi rimandata a classi concrete

non note

w  Indirizzano però problemi diversi •  Il Template Method è il metodo che invoca i metodi

astratti, al fine di generalizzare un algoritmo •  Il Factory Method è un metodo astratto che deve creare e

restituire l’istanza di classe concreta, al fine di sganciare il cliente dalla scelta del tipo specifico

Uniroma2 - Arch. e Servizi SW per Internet!

63

Strategy w  Scopo: Definire ed incapsulare una

famiglia di algoritmi in modo da renderli intercambiabili indipendentemente dal client che li usa.

w Motivazione: Consideriamo la famiglia degli algoritmi di ordinamento. Ne esistono diversi (QuickSort, BubbleSort, MergeSort), ecc… Costruiamo una applicazione che li supporti tutti, possa essere facilmente estendibile, e permetta una scelta rapida del tipo di algoritmo. Classificazione: comportamentale basato su oggetti

Uniroma2 - Arch. e Servizi SW per Internet!

64

Strategy : esempio

sort()

QuickSorter

sort()

MergeSorter

sort()

SelectionSorter

sort()

Sorter Client

Gli algoritmi di ordinamento devono essere indipendenti dal vettore di dati su cui operano, e dal resto dell’implementazione dell’applicazione

Uniroma2 - Arch. e Servizi SW per Internet!

65

Strategy: struttura

algorithm()

ConcreteStrategyA

algorithm()

ConcreteStrategyB

algorithm()

ConcreteStrategyC

algorithm()

Strategy

Client

Uniroma2 - Arch. e Servizi SW per Internet!

66

Altre caratteristiche w  Applicabilità

•  Molte classi correlate differiscono solo per il comportamento. Il pattern fornisce un modo per avere una interfaccia comune.

•  Sono necessarie più varianti di uno stesso algoritmo, a seconda dei tipi di dato in ingresso o delle condizioni operative.

w  Partecipanti •  Strategy e ConcreteStrategy •  Client

Uniroma2 - Arch. e Servizi SW per Internet!

67

Altre caratteristiche w  Conseguenze:

•  Il pattern separa l’implementazione degli algoritmi dal contesto dell’applicazione.

•  Le diverse strategie eliminano i blocchi condizionali che sarebbero necessari inserendo tutti i diversi comportamenti in una unica classe.

•  Lo svantaggio principale è che i client devono conoscere le diverse strategie.

usare il subclassing della Classe client per aggiungere un algoritmo non sarebbe stata una buona scelta.

Uniroma2 - Arch. e Servizi SW per Internet!

68

Design Pattern - Esercizi

Uniroma2 - Arch. e Servizi SW per Internet!

69

Esercizio 1 w  Realizzare una applicazione per gestire il

download da siti http e ftp. La selezione avviene in base all'inizio dell’url (ftp o http)

suggerimento: usare una factory e uno strategy pattern....

Uniroma2 - Arch. e Servizi SW per Internet!

70

Soluzione 1/1 w  L’applicazione deve gestire il download da

siti supportando solo due protocolli. w  E’ ragionevole scrivere una applicazione

che sia estendibile senza problemi (manutenzione evolutiva)

w  Usiamo un pattern Strategy per implementare il download secondo i due protocolli.

Uniroma2 - Arch. e Servizi SW per Internet!

71

Soluzione 1/2

getFile(URL, dest)

FTPStrategy

getFile(URL, dest)

HTTPStrategy

getFile(URL, dest)

ProtocolStrategy

DownloadApp download( String url, String dest ) {

ProtocolStrategy ps=null; url = url.toLowerCase(); if( url.startsWith( "ftp” ) ) { ps = new FtpStrategy(); } else if( url.startsWith( "http” ) ) { ps = new HttpStrategy(); } else { //No operation available }

ps.getFile( url, dest ); }

Uniroma2 - Arch. e Servizi SW per Internet!

72

Soluzione 1/3 w  In questo modo ogni volta che vogliamo

aggiungere un nuovo protocollo dobbiamo modificare la classe DownloadApp.

w  DownloadApp in questo scenario deve conoscere alcuni dettagli implementativi: ad esempio deve sapere esattamente quali protocolli sono supportati e come si chiamano le relative classi di gestione.

w  Introduciamo quindi una Factory…

Uniroma2 - Arch. e Servizi SW per Internet!

73

Soluzione 1/4

getFile(URL, dest)

FTPStrategy

getFile(URL, dest)

HTTPStrategy

DownloadApp

create(URL)

ProtocolFactory

create(URL)

Creator

getFile(URL, dest)

ProtocolStrategy

Uniroma2 - Arch. e Servizi SW per Internet!

74

Soluzione 1/5

La Factory Contiene la logica per creare la corretta sottoclasse di ProtocolStrategy

abstract class Creator { public abstract ProtocolStrategy create( String url );

} class ProtocolFactory extends Creator {

public ProtocolStrategy create( String ind ){ ind = ind.toLowerCase(); if( ind.startsWith( "ftp" ) ) { return new FtpStrategy(); } else if( ind.startsWith( "http" ) ) { return new HttpStrategy(); } else { //throw an exception… } }

}

Uniroma2 - Arch. e Servizi SW per Internet!

75

Soluzione 1/6

class Download{ …

download( String url, String dest ) { ProtocolFactory p = new ProtocolFactory(); ProtocolStrategy ps = p.create(url); ps.getFile(url,dest); }

}

abstract class ProtocolStrategy {

abstract void getFile(String ind, String dest); }

class FtpStrategy extends ProtocolStrategy {

public void getFile(String url, String dest) { //…method impementation }

} … ProtocolStrategy ps = ProtocolFactory.create(url);

Alternativa Statica

Uniroma2 - Arch. e Servizi SW per Internet!

76

Soluzione 1/6 w  Nel caso si utilizzi un metodo statico, la

classe astratta Creator deve essere modificata perché il metodo create() deve essere implementato.

w  In questo caso quindi la classe ProtocolFactory che eredita da Creator, per avere senso, dovrebbe arricchire di responsabilità la classe.

w  In alternativa l’applicazione può invocare il metodo statico della classe astratta.

Uniroma2 - Arch. e Servizi SW per Internet!

77

Esercizio 2 w  Descrivere un modello a oggetti che

rappresenti gli Impiegati di una azienda.

w  Gli impiegati possono avere delle responsabilità aggiuntive: possono essere CapoArea o CapoProgetto, in modo non esclusivo.

w  Una particolare categoria di impiegati che ci interessa sono naturalmente gli Ingegneri

suggerimento: usare il Decorator Pattern per le responsabilità, e l’ereditarietà per contraddistinguere gli Ingegneri dagli Impiegati

Gli impiegati hanno tutti il metodo chiSono() che visualizza il nome e la particolare responsabilità

Uniroma2 - Arch. e Servizi SW per Internet!

78

Soluzione 2/1 w  Dall’esame dei requisiti si può provare a

disegnare una struttura con queste caratteristiche: •  Deve esistere una classe Impiegato che

definisce una interfaccia comune (metodo chiSono() )

•  Deve esistere una classe Ingegnere che eredita da Impiegato

•  Definiamo con il pattern Decorator due classi CapoArea e CapoProgetto

Uniroma2 - Arch. e Servizi SW per Internet!

79

Soluzione 2/2

chiSono()

Ingegnere

chiSono()

RespDecorator

chiSono()

CapoProgetto

chiSono

CapoArea

chiSono()

<<interface>> Impiegato

Uniroma2 - Arch. e Servizi SW per Internet!

80

Soluzione 2/3 public interface Impiegato {

public void chiSono(); public void getName();

}

public class Ingegnere implements Impiegato { private String nome; public Ingegnere( String nome) { this.nome = nome; } public String getName () { return nome; } public void chiSono() { System.out.println( “Salve, sono l’Ing. " + getName());

} }

chiSono()

Ingegnere

chiSono()

<<interface>> Impiegato

Uniroma2 - Arch. e Servizi SW per Internet!

81

Soluzione 2/4 abstract class RespDecorator implements Impiegato {

protected Impiegato responsabile; public RespDecorator(Impiegato imp) { responsabile = imp; } public String getName() { return responsabile.getName(); } public void chiSono() { responsabile.chiSono(); }

}

chiSono()

RespDecorator

chiSono()

<<interface>> Impiegato

Uniroma2 - Arch. e Servizi SW per Internet!

82

Soluzione 2/5 public class CapoProgetto extends RespDecorator {

public CapoProgetto ( Impiegato imp ) { super( imp );

} public void chiSono() {

super.chiSono(); System.out.println(“e sono anche un CapoProgetto!”)

}

chiSono()

RespDecorator

chiSono()

CapoProgetto

chiSono

CapoArea

Uniroma2 - Arch. e Servizi SW per Internet!

83

Soluzione 2/6 Impiegato pippo = new Ingegnere(“Pippo”); pippo.chiSono(); pippo = new CapoProgetto(pippo)); pippo.chiSono(); Impiegato pluto = new CapoProgetto(new

Ingegnere(“Pluto”)); pluto.chiSono();

Salve, sono l’ing. Pippo

Salve, sono l’ing. Pluto e sono anche un CapoProgetto!

Salve, sono l’ing. Pippo e sono anche un CapoProgetto!

Uniroma2 - Arch. e Servizi SW per Internet!

84

Esercizio 3 w  Consideriamo un oggetto Subject che

riceve valori dall’esterno e che in modo casuale cambia il suo stato interno accettando o meno il valore ricevuto.

w  Due oggetti Watcher e Psicologist devono monitorare il cambiamento di valore di Subject.

w  Utilizzare il pattern Observer sfruttando le capability di Java suggerimento: usare le interfacce Observer ed Observable

Uniroma2 - Arch. e Servizi SW per Internet!

85

Soluzione 3/1

addObserver(Observer o) deleteObserver(Observer o) setChanged() notify()

java.util.Observable

receiveValue(int n) getValue()

Subject

int state

update(Observable s, Object arg)

<<interface>> Observer

update(Observable s, Object arg)

Watcher

update(Observable s, Object arg)

Psycologist

Uniroma2 - Arch. e Servizi SW per Internet!

86

Soluzione 3/2 import java.util.Observer; import java.util.Observable; public class Subject extends Observable {

private int value = 0; public void receiveValue( int newNumber ) { if (Math.random() < .5) { System.out.println( "Subject : Ho cambiato il mio stato“); value = newNumber; this.setChanged(); } else System.out.println( "Subject : Stato interno invariato ); this.notifyObservers(); }

public int returnValue() { return value; }

}

Uniroma2 - Arch. e Servizi SW per Internet!

87

Soluzione 3/3 import java.util.Observer; import java.util.Observable; public class Watcher implements Observer {

private int changes = 0; public void update(Observable obs, Object arg) { System.out.println( "Watcher: Lo stato del subject è: " + ((ObservedSubject) obs ).returnValue() + "."); changes++; } public int observedChanges() { return changes; }

}

Uniroma2 - Arch. e Servizi SW per Internet!

88

Soluzione 3/4 public class Esempio {

public static void main (String[] args) { … s.addObserver( o ); s.addObserver( p ); for(int i=1;i<=10;i++){ System.out.println( "Main : Invio il numero " + i ); s.receiveValue( i ); } System.out.println( “Il subject ha cambiato stato " + o.observedChanges() + " volte."); … }

}

Main : Invio il numero 1 Subject : Stato interno invariato Main : Invio il numero 2 Subject : Ho cambiato il mio stato Watcher: Lo stato del subject è: 2. … Il subject ha cambiato stato 4 volte.

Uniroma2 - Arch. e Servizi SW per Internet!

89

Esercizio 4 w  Realizzare un semplice Editor in grado di

gestire elementi grafici costituiti dai seguenti elementi elementari: •  Righe, testi, immagini

w  L’editor deve supportare due diversi algoritmi di formattazione

w  L’editor deve supportare elementi grafici complessi come le barre di scorrimento o dei bordi grafici suggerimento: usare i pattern Composite, Strategy, Decorator....

Uniroma2 - Arch. e Servizi SW per Internet!

90

Soluzione 4/1 w  La struttura degli elementi tipografici può

essere resa con un Composite Pattern w  La gestione degli algoritmi di formattazione

può essere disaccoppiata ed estendibile utilizzando il pattern Strategy

w  Il controllo delle funzionalità grafiche può essere ottenuto utilizzando il Decorator Pattern elementi grafici

Uniroma2 - Arch. e Servizi SW per Internet!

91

Soluzione 4/2 w  Per semplicità non consideriamo la

struttura logica di un documento (paragrafi, capitoli, sezioni) ma sono una rappresentazione degli elementi semplici (riga, testo, immagine)

elemento

riga riga

testo immagine

Uniroma2 - Arch. e Servizi SW per Internet!

92

Soluzione 4/3

draw() insert(ElementoGrafico)

ElementoGrafico

draw()

Testo

draw() Insert(ElementoGrafico)

Riga children

draw()

Immagine

Rappresentazione degli elementi grafici: il pattern Composite

Nota: In Java le classi foglia (Immagine e Testo) devono necessariamente implementare il metodo insert() previsto dalla classe astratta. In questo caso una possibile soluzione è che queste generino una eccezione apposita

Uniroma2 - Arch. e Servizi SW per Internet!

93

Soluzione 4/4

draw() insert(ElementoGrafico)

ElementoGrafico

Insert(ElementoGrafico)

Composition

compose()

Compositor

Rappresentazione degli algoritmi di formattazione: il pattern Strategy

compose()

Justify

compose()

RightAlign

Uniroma2 - Arch. e Servizi SW per Internet!

94

Soluzione 4/5

draw() insert(ElementoGrafico)

ElementoGrafico

compose()

Decorator

compose()

ScrollBar

compose()

Border

Rappresentazione delle proprietà grafiche: il pattern Decorator

Uniroma2 - Arch. e Servizi SW per Internet!

95

Soluzione 4/6

draw() insert(ElementoGrafico)

ElementoGrafico

compose()

Decorator

compose()

ScrollBar

compose()

Border

draw()

Testo

draw() Insert(ElementoGrafico)

Riga

draw()

Immagine

Insert(ElementoGrafico)

Composition

compose()

Compositor

compose()

Justify

compose()

RightAlign

Mettendo tutto insieme…

Uniroma2 - Arch. e Servizi SW per Internet!