32
Design Patterns Parte 2

Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Design Patterns Parte 2

Page 2: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

2

Builder Design Pattern

Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione è riusato per creare oggetti che hanno differenti forme di rappresentazione.

L’interfaccia Builder specifica i metodi necessari per creare le parti di cui è composto un oggetto complesso. Spesso tali

metodi sono Factory Methods.

Partecipanti nel Builder Pattern

Builder ConcreteBuilder Director Product

Page 3: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

3

Product

ConcreteBuilder

buildPartA() buildPartB() getResult()

Directorconstruct()

BuilderbuildPartA()buildPartB()

Client

for all parts in structure { builder->buildPart() }

Struttura dei Partecipanti

Page 4: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

4

Diagrammi di Sequenza

Page 5: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

5

Quando si usa il Builder Pattern• Quando l’algoritmo per costruire un oggetto complesso dovrebbe rimanere indipendente dalle

parti che lo compongono e da come tali parti sono rappresentate ed assemblate. • Quando la costruzione di un oggetto complesso deve consentire la specifica di

rappresentazioni e modelli dei dati alternative e tali scelte devono essere differibili a tempo di esecuzione.

• Quando si costruiscono oggetti compositi che hanno una struttura interna non elementare.

Conseguenze

Importante: Il Builder Design Pattern fornisce controllo a tutti i livelli del processo di

costruzione.

• Seleziona la rappresentazione interna di un oggetto a tempo di creazione • Disaccoppia il codice che definisce la struttura di un oggetto da quello che crea le

singole parti che lo compongono

Page 6: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

6

Design PatternsPatterns strutturali (28/64)

Introduzione

! Riguardano il modo in cui classi ed oggetti sono legati tra loro in strutture più grandi e/o complesse.

! I pattern strutturali per le classi usano l'ereditarietà per comporre insieme diverse interfacce o implementazioni.

! I pattern strutturali per gli oggetti descrivono modi di comporre oggetti che realizzano nuove funzionalità.

! I pattern strutturali utilizzano ereditarietà per comporre interfacce o implementazioni: es. è possibile utilizzare un pattern strutturale per combinare più classi. Tale pattern risulta utile per rendere interoperabili librerie sviluppate in maniera indipendente l’una dall’altra.

Iniziamo con: ! Adapter (class) "! Adapter (object)

Page 7: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

7

DP : Adapter (Strutturale)"

■ Nome: Adapter "

■ Sinonimo : Wrapper "

■ Scopo : Converte l’interfaccia di una classe in un’altra interfaccia, attesa da un cliente ( quindi permette la

cooperazione di classi che altrimenti avrebbero interfacce incompatibili)

"■ Motivazione : In alcune circostanze non si potrebbe utilizzare

una classe già esistente e collaudata solo perché quest’ultima non comunica più con una interfaccia specializzata richiesta da

un’applicazione.

Design PatternsPatterns strutturali (29/64)

Page 8: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

8

DP : Adapter■ Struttura :

Design PatternsPatterns strutturali (30/64)

Page 9: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

9

DP : Adapter■ Struttura ( alternativa):

Design PatternsPatterns strutturali (31/64)

Page 10: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

10

Class Adapter Structure

Varia

nt 1

: Im

plem

enta

tion

inhe

ritan

ce

Varia

nt 2

: A

ssoc

iatio

n

Design PatternsPatterns strutturali (32/64)

Object Adapter Structure

Page 11: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

11

DP : Adapter■ Esempio: un editor grafico usa una classe Shape per editare e

visualizzare gli oggetti grafici. "

■ Il progettista possiede una classe riusabile TextView per editare e visualizzare testo.

"■ Purtroppo TextView non sa nulla di Shape.

"■ Possiamo però definire una nuova classe TextShape che

incapsuli TextView e adatti la sua interfaccia a quella di Shape.

Design PatternsPatterns strutturali (33/64)

Page 12: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

12

DP : Adapter■ Esempio concreto di adattatore

Design PatternsPatterns strutturali (34/64)

Page 13: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

13

DP : Adapter"

■ Applicabilità: Adapter puo essere utilizzato :

1. Se si vuole utilizzare una classe esistente la cui interfaccia sia incompatibile

2. Se si vuole creare una classe (riusabile) che dovrà collaborare con classi non prevedibili al momento della

sua creazione 3. Se si vuole riusare un insieme di sottoclassi esistenti,

ma è scomodo adattare l’interfaccia creando una sottoclasse per ciascuna: meglio creare un adattatore

Design PatternsPatterns strutturali (35/64)

Page 14: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

14

Adapter! Partecipanti :

– Target : definisce l’interfaccia specializzata usata dal client (Es.

Shape) – Client : collabora con oggetti conformi

all’interfaccia target (Es. DrawEditor)

– Adaptee : definisce un ‘interfaccia che deve essere resa conforme (Es.

TextView) – Adaptor : adatta l’interfaccia di adaptee

all’interfaccia Target (Es. TextShape)

Design PatternsPatterns strutturali (36/64)

Page 15: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

15

Esempio codice C++class Shape { public: Shape(); virtual void BoundingBox(Point& bottomLeft, Point& topRight) const; virtual Manipulator* CreateManipulator() Const; }; ""class TextView { public: TextView(); void GetOrigin(Coord& x, Coord& y) const; void GetExtent(Coord& width, Coord& height) const; virtual bool IsEmpty() const; };

Design PatternsPatterns strutturali (39/64)

Page 16: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

16

Esempio codice C++class TextShape: public Shape, private TextView { public: TextShape(); virtual void BoundingBox( Point& bottomLeft, Point& topRight) const; virtual bool IsEmpty() const; virtual Manipulator* CreateManipulator() Const; }; // Implementazione TextShape::BoundingBox void TextShape::BoundingBox(Point& bottomLeft, Point& topRight) const { Coord bottom, left, width, height; GetOrigin(bottom,left); GetExtent(width,height); bottomLeft=Point(bottom,left); topRight=Point(bottom+height,left+width) };

Design PatternsPatterns strutturali (40/64)

Ereditarietà privata e multipla

Page 17: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

17

/* New Adaptor class */ class MyStringComparator implements Comparator { /* ... */ int compare (Object o1, Object o2) { int result; if (o1.greaterthan(o2)) { result = 1;

} else if (o1.equals(o2)) { result = 0;

} else { result = -1;

} return result;

} }

Adapter Example II

Page 18: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

18

Design PatternsPatterns comportamentali (44/64)

Introduzione

! I behavioral pattern riguardano la definizione/gestione di algoritmi e le assegnazioni di responsabilità tra le diverse classi ed oggetti: essi descrivono le modalità di comunicazione tra gli oggetti, oltre che le relazioni tra gli stessi.

! I behavioral class patterns utilizzano l’ereditarietà per distribuire comportamenti tra diverse classi

! I behavioral object patterns utlizzano composizione piuttosto che ereditarietà ! In linea del tutto generale, si utilizza un behavioral pattern per incapsulare

comportamenti. I behavioral patterns che tratteremo oggi sono i seguenti: ! Observer = Definisce una relazione di dipendenza tra un oggetto “osservato” e un

insieme qualsiasi di “osservatori”. Essi vengono notificati di ogni cambiamento di stato dell'oggetto osservato.

Page 19: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

19

! Intento: Definire una relazione uno a molti tra oggetti, in modo che quando un oggetto cambia stato, ciò è notificato a tutti gli oggetti dipendenti

! Alias: Dependant, Publish-Subscribe ! Motivazioni: Es. consideriamo i grafici prodotti da uno spreadsheet.

Cambiando i dati di origine, i grafici si aggiornano automaticamente. L’interazione avviene tra un subject ed un numero qualsiasi di observer dipendenti, che vengono notificati quando cambia lo stato del subject.

"! Applicabilità: l’Observer andrebbe usato quando:

– Un’astrazione ha due aspetti, una dipendente dall’altra, e si desidera incapsulare le due astrazioni in oggetti separati;

– Se cambiamenti ad un oggetto richiedono di cambiarne altri, senza sapere quali;

– Quando un oggetto deve essere in grado di notificare qualcosa ad un’altro oggetto non noto a priori.

""

Design PatternsPatterns comportamentali (45/64)

Observer (1/5)

Page 20: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

20

Struttura:

Design PatternsPatterns comportamentali (46/64)

Observer (2/5)

Page 21: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

21

! Collaborations: – Il ConcreteSubject notifica ai propri Observers quando ha luogo un cambiamento

che porterebbe l’Observer in uno stato inconsistente. – Dopo essere stato informato del cambiamento, il ConcreteObserver effettua una

query sul Subject per richiedere informazioni, e le utilizza poi per riallineare il proprio stato con quello del Subject stesso.

""

Design PatternsPatterns comportamentali (47/64)

Observer (3/5)

Page 22: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

22

"■ Conseguenze:

! Accoppiamento astratto tra Subject e Observer: un Subject sa che ha una lista di Observer, conformi ad un’interfaccia astratta (AbstractObserver), ma non è a conoscenza delle classi concrete degli stessi;

"! Supporto alla comunicazione di tipo multicast; "! Aggiornamenti inattesi: se le interdipendenze non sono ben

formate, possono verificarsi aggiornamenti a cascata indesiderati.

"

Design PatternsPatterns comportamentali (48/64)

Observer (4/5)

Page 23: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

23

Design PatternsPatterns comportamentali (49/64)

Observer (5/5)Implementazione:

Page 24: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

! Intento: Incapsulare una richiesta in un oggetto, in modo tale da parametrizzare i client rispetto a richieste differenti, consentendo operazioni come accodamento, logging e undo.

! Noto come: Action, Transaction ! Motivazioni: Oggetti di un toolkit possono effettuare richieste

trasformando le richieste stesse in oggetti. La “chiave” del pattern è la classe Command, che dichiara un’interfaccia per l’esecuzione delle operazioni (metodo Execute()). Le classi ConcreteCommand specificano la coppia azione-ricevente implementando tale metodo, e immagazzinando il ricevente in una variabile di istanza.

Design PatternsPatterns strutturali

Command (1/9)

Page 25: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Design PatternsPatterns strutturali

Command (2/9)

Page 26: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Come è possibile notare, i menu possono essere implementati agevolmente con tale pattern. Ciascuna scelta del Menu è un’istanza della classe MenuItem. L’Application crea il Menu e tiene traccia dei Documents aperti. Ciascun MenuItem è associato ad un’istanza di una classe ConcreteCommand.

Design PatternsPatterns strutturali

Command (3/9)

Page 27: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Design PatternsPatterns strutturali

Command (4/9)

Page 28: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

! Applicabilità: Il Command è utile per: – Parametrizzare oggetti rispetto ai comandi da eseguire (ciò nei

linguaggi procedurali spesso avviene per mezzo di una callback, ovvero una funzione registrata in un certo punto per poi essere richiamata successivamente);

– Specificare, accodare ed esegure richieste in tempi diversi; – Supportare l’undo: l’operazione di Execute può mantenere lo stato

per annullare il proprio effetto; – Supppotare il logging dei comandi in modo da consentire il redo in

caso di crash del sistema; – Eseguire transazioni atomiche.

Design PatternsPatterns strutturali

Command (5/9)

Page 29: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Struttura:

Design PatternsPatterns strutturali

Command (6/9)

Page 30: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

! Collaborations: – Il client crea un ConcreteCommand e specifica il

proprio ricevente; – L’Invoker immagazzina il ConcreteCommand; – Il ConcreteCommand invoca operazioni sul

ricevente per eseguire le richieste.

Design PatternsPatterns strutturali

Command (7/9)

Page 31: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

Collaborations:

Design PatternsPatterns strutturali

Command (8/9)

Page 32: Design Patterns Parte 2 · 2 Builder Design Pattern Separa la costruzione di un oggetto complesso dalla rappresentazione delle parti che lo compongono: lo stesso processo di costruzione

! Conseguenze: – Il Command disaccoppia l’oggetto che invoca l’operazione

da quello che la esegue; – Un Command può essere manipolato o esteso come

qualsiasi altro oggetto; – E’ possibile assemblare Commands creando dei comandi

composti; – Aggiungere nuovi Command risulta semplice, e non

richiede modifiche alle classi esistenti.

Design PatternsPatterns strutturali

Command (9/9)