Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Ingegneria
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Porfirio Tramontana » 15.Design Patterns – Parte prima


Storia

Introdotti dall’architetto (di edifici, non di software) Christopher Alexander.
Ogni pattern descrive un problema che si presenta frequentemente nel nostro ambiente, e quindi descrive il nucleo della soluzione così che si possa impiegare tale soluzione milioni di volte, senza peraltro produrre due volte la stessa realizzazione.

Il principio è ugualmente valido, anche se riferito ad oggetti, classi ed interfacce piuttosto che ad elementi architettonici come muri, archi, pilastri, ecc.

Pattern

Un Pattern

  • individua un’IDEA, uno schema GENERALE E RIUSABILE
    • schema di problema,
    • schema di soluzione, etc.
  • non è paragonabile ad un componente riusabile perchè
    • non è un “oggetto” fisico;
    • non può essere usato così come è stato definito, ma deve essere contestualizzato all’interno del particolare problema applicativo.
  • due istanze/contestualizzazioni di uno stesso pattern (ad esempio in problemi diversi) tipicamente sono diverse proprio per la contestualizzazione in domini differenti.

Scopo dei Patterns

  • Scopo dei pattern
    • Catturare l’esperienza e la “saggezza” degli esperti;
    • Evitare di reinventare ogni volta le stesse cose.
  • Cosa fornisce un design pattern al progettista software?
    • Una soluzione codificata e consolidata per un problema ricorrente;
    • Un’astrazione di granularità e livello di astrazione più elevati di una classe;
    • Un supporto alla comunicazione delle caratteristiche del progetto;
    • Un modo per progettare software con caratteristiche predefinite;
    • Un supporto alla progettazione di sistemi complessi.

Definizione

Definizione: Ogni pattern descrive un problema specifico che ricorre più volte e descrive il nucleo della soluzione a quel problema, in modo da poter utilizzare tale soluzione un milione di volte, senza mai farlo allo stesso modo.

Abbastanza astratti
- in modo da poter essere condivisi da progettisti con punti di vista diversi.

Non complessi nè domain-specific
- non rivolti alla specifica applicazione ma riusabili in parti di applicazioni diverse.

Caratteristiche

Un Design Pattern

  • Nomina
  • Astrae
  • Identifica

gli aspetti chiave di una struttura comune di design che la rendono utile nel contesto del riuso in ambito object-oriented.

  • Un Design Pattern identifica
    • le classi (e le istanze) partecipanti;
    • le associazioni ed i ruoli;
    • le modalità di collaborazione tra le classi coinvolte;
    • la distribuzione delle responsabilità nella soluzione del particolare problema di design considerato.

Tipologie di pattern

Esistono diverse tipologie di pattern, che si differenziano principalmente per la scala ed il livello di astrazione:

  • Architectural Pattern
    • Utili per strutturare un sistema in sottosistemi;
  • Design Pattern
    • Operano essenzialmente a livello di un singolo sottosistema evidenziando le caratteristiche delle classi coinvolte e delle associazioni tra le classi;
  • Idioms
    • Utili per l’implementazione di specifici aspetti di design in un particolare linguaggio di programmazione.

Come sono fatti i Design Patterns

Un pattern è formato da quattro elementi essenziali:

  1. Il nome del pattern, è utile per descrivere la sua funzionalità in una o due parole.
  2. Il problema nel quale il pattern è applicabile. Spiega il problema e il contesto, a volte descrive dei problemi specifici del design mentre a volte può descrivere strutture di classi e oggetti. Può anche includere una lista di condizioni che devono essere soddisfatte precedentemente perché il pattern possa essere applicato.
  3. La soluzione che descrive in modo astratto come il pattern risolve il problema. Descrive gli elementi che compongono il design, le loro responsabilità e le collaborazioni.
  4. Le conseguenze portate dall’applicazione del pattern. Spesso sono tralasciate ma sono importanti per poter valutare i costi-benefici dell’utilizzo del pattern.

Schema di Descrizione DP

  • Nome e classificazione del pattern
  • Sinonimi: altri nomi del pattern
  • Scopo: cosa fa il pattern? a cosa serve?
  • Motivazione: scenario che illustra un design problem
  • Applicabilità: situazioni in cui si applica il pattern
  • Struttura: rappresentazione delle classi in stile OMT
  • Partecipanti: classi e oggetti inclusi nel pattern
  • Collaborazioni: come i partecipanti collaborano
  • Conseguenze: come consegue i suoi obiettivi il pattern?
  • Implementazione: che tecniche di codifica sono necessarie?
  • Codice di esempio: scritto in un linguaggio a oggetti
  • Usi noti: esempi d’applicazione del pattern in sistemi reali
  • Pattern correlati: con quali altri pattern si dovrebbe usare?

Categorie di Pattern

Un esempio di catalogo DP è presente nel libro Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, “Design Patterns: Elements of Reusable Object Oriented Software”.
I pattern qui descritti sono spesso denominati pattern GoF (Gang of Four), per ricordarne i 4 autori.

Esistono diverse categorie di pattern, che descrivono la funzione (purpose) e il dominio (scope) del pattern.

  • Funzione (purpose), ovvero cosa fa il pattern:
    • Creazionali (creational): forniscono meccanismi per la creazione di oggetti;
    • Strutturali (structural): gestiscono la separazione tra interfaccia e implementazione e le modalità di composizione tra oggetti;
    • Comportamentali (behavioral): consentono la modifica del comportamento degli oggetti minimizzando le necessità di cambiare il codice.

Categorie di Pattern (segue)

Dominio (scope), indica se il pattern si applica a classi o oggetti:

  • Class pattern
    • Si focalizzano su relazioni fra classi e sottoclassi. Tipicamente si riferiscono a situazioni statiche (Es. relazioni espresse attraverso l’ereditarietà), ovvero riguardano il compile-time.
  • Object pattern
    • Si focalizzano su oggetti (istanze) e loro relazioni.Tipicamente si riferiscono a situazioni dinamiche (le relazioni tra oggetti possono ovviamente cambiare a run-time).

La differenza è comunque molto sfumata.

DPA Toolkit

Free software che permette di:

  • Disegnare Class Diagrams;
  • Disegnare Class Diagrams contenenti Design Patterns;
  • Generare codice sorgente in C++, C#, Java, VB.NET conforme al class diagram disegnato;
  • Ricostruire diagrammi delle classi a partire dal codice, riconoscendo eventuali istanziazioni di design pattern.

Scaricabile da: dpatoolkit

Categoria Creational

Questa categoria raccoglie i pattern che forniscono un’astrazione per il processo di istanziazione.

Questi pattern permettono di rendere un sistema indipendente da come sono creati, rappresentati e composti gli oggetti al suo interno.

Categoria Creational (segue)


DP: Singleton (Creazionale)

Nome: Singleton.

Scopo: Costruire classi che supportino una e una sola istanza di oggetto e forniscono un punto d’accesso globale a tale istanza.


Esempio

  • Il puntatore _instance è static, quindi persiste al variare degli oggetti;
  • Il puntatore _instance è private, quindi non può essere modificato dall’esterno;
  • Il puntatore _instance è inizializzato staticamente a zero, quindi è sempre interrogabile;
  • Il costruttore è protetto in modo da poter essere invocato solo da Instance();
  • Il puntatore all’oggetto è ottenibile da chiunque chiamando il metodo pubblico Instance().

Categoria Structural

I pattern di questa categoria sono dedicati alla composizione di classi e oggetti per creare delle strutture più grandi.

È possibile creare delle classi che ereditano da più classi per consentire di utilizzare proprietà di più superclassi indipendenti.

Ad esempio permettono di far funzionare insieme delle librerie indipendenti.

Categoria Structural (segue)


Categoria Structural (segue)


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 con l’interfaccia richiesta dalla nostra applicazione.

Partecipanti:

  • Target: definisce l’interfaccia specializzata usata dal client;
  • Client: collabora con oggetti conformi all’interfaccia target;
  • Adaptee: definisce un ‘interfaccia che deve essere resa conforme;
  • Adapter: adatta l’interfaccia di adaptee all’interfaccia Target.

DP: Adapter (segue)

Struttura del DP Adapter

Struttura del DP Adapter


DP: Adapter (segue)

Struttura alternativa per il DP Adapter

Struttura alternativa per il DP Adapter


DP: Adapter (segue)

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.

DP: Adapter (segue)

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 per la classe genitore.

DP: Adapter (segue)

Conseguenze:

  • Sulla Classe:
    • Adapter ridefinisce (overrides) parte del comportamento di Adaptee;
    • una classe particolare adatta Adaptee a Target concretizzando un Adapter, quindi non è possibile adattare una classe e tutte le sue sottoclassi.
  • Sull’oggetto:
    • Gli Adapter possono funzionare in molti modi, dalla conversione di interfaccia alla completa ridefinizione e integrazione dei metodi; la quantità di lavoro svolta da un Adapter dipenderà da quanto simili sono il Target voluto e l’Adaptee disponibile.

Esempio codice C++

// Target
class Shape
{
public:
Shape();
virtual void BoundingBox(Point& bottomLeft, Point& topRight) const;
virtual Manipulator* CreateManipulator() Const;
};

// Adaptee
class TextView
{
public:
TextView();
void GetOrigin(Coord& x, Coord& y) const;
void GetExtent(Coord& width, Coord& height) const;
virtual bool IsEmpty() const;
};

Esempio codice C++

// Adapter
class TextShape: public Shape, private TextView
{ //eredita privatamente da TextView, perché non vuole inoltrare l'ereditarietà
public:
TextShape();
void BoundingBox(Point& bottomLeft, Point& topRight) const;
virtual bool IsEmpty() const;
Manipulator* CreateManipulator() Const;
};

// Implementazione TextShape::BoundingBox
void TextShape::BoundingBox(Point& bottomLeft, Point& topRight) const
{
Coord bottom, left, width, height;
GetOrigin(bottom,left); // metodi ereditati da TextView
GetExtent(width,height);
bottomLeft=Point(bottom,left);
topRight=Point(bottom+height,left+width)
};

Esempio

Nella realizzazione di un software object oriented per il mercato statunitense si vuole realizzare una classe Health che fornisca, tra l’altro, l’indice di massa corporeo (IMC) di una persona, secondo l’interfaccia riportata di lato.

Non conoscendo l’algoritmo che permette di calcolare tale indice, si decide di riutilizzare una classe IMC, presa da un software realizzato per il mercato italiano che dispone della seguente interfaccia.

Sono note le seguenti relazioni tra unità di misura:
1 libbra è pari a 0,453 kilogrammi
1 pollice è pari a 0,0254 metri

- Si progetti il class diagram a livello di dettaglio che sia in grado di risolvere il problema proposto svincolando il programmatore della classe Health dalla conoscenza dell’interfaccia e dell’implementazione della classe IMC, utilizzando il design pattern Adapter.


Soluzione possibile


I materiali di supporto della lezione

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, "Design Patterns: Elements of Reusable Object Oriented Software".

Marcello Esposito, Elementi per la progettazione di Software Object-Oriented riusabile ed estensibile.

dofactory

dpatoolkit

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion