|
È molto più bello sapere qualcosa di tutto, che tutto di
una cosa
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
Design Pattern - Introduzione
By
Luana Rinaldi
18 dicembre 2007
|
 |
|
Una delle principali direttive della progettazione Object-Oriented consiste nello sviluppare classi e metodi che possano essere riusabili in altri contesti; infatti, molto spesso nell’affrontare la progettazione di diversi applicativi, si ha la sensazione di dover risolvere un problema noto, già affrontato in precedenza, ma, a causa della mancata analisi sistematica e precisa della soluzione adottata e della stesura della relativa documentazione tecnica, si è costretti a sviluppare nuovamente una soluzione per lo stesso problema. L’esperienza di un progettista, invece, si misura anche nella consapevolezza di non dover affrontare la progettazione di un componente da zero, ma di riutilizzare soluzioni già sperimentate e collaudate in precedenza, spendendo, quindi, solo il tempo necessario per l’adattamento della stessa al contesto di dominio specifico. In questo modo, la progettazione diviene esperta, ossia utilizza delle direttive per la risoluzione di problemi noti, con l’intento di rendere il codice finale elegante e chiaro, e soprattutto riusabile per applicazioni future. Questo tipo di approccio consente anche uno sviluppo più rapido del software, in quanto risulta possibile concentrare l’attenzione su problemi di dominio e non su dettagli tecnici o implementativi.
Un ulteriore vantaggio dell’utilizzo di queste strutture consiste nel dare al codice le caratteristiche di robustezza ed estensibilità caratteristici delle applicazioni che rispettano l’Object Oriented. Infatti, l’applicazione di queste soluzioni consente di mantenere validi i principi di questo paradigma di programmazione, ossia l’incapsulamento, l’ereditarietà e il polimorfismo. Il rispetto di questi principi permette inoltre di ottenere un codice corretto, robusto, e poco sensibile a modifiche o estensioni.
Alla luce di questo, un progettista esperto dovrebbe, quindi, conoscere un insieme strutturato e nutrito di quelli che vengono chiamati pattern, in modo da velocizzare i tempi di analisi, dedicandosi soltanto alle specifiche di dominio. I pattern, infatti, concentrano la loro attenzione sulle parti invarianti della loro applicazione, in modo da permettere un adattamento ad ogni tipo di situazione: questo significa che la descrizione di un pattern, così come viene presentata nel Catalogo dei Pattern [4], deve essere abbastanza concreta da essere messa immediatamente in pratica, ma sufficientemente astratta da poter essere applicabile in situazioni diverse, evitando così di limitarne l’utilizzo da parte degli stessi progettisti.
|
|
|
I Pattern
|
top
|
Letteralmente, i pattern costituiscono ‘motivi ricorrenti di progettazione’, ossia presentano delle “soluzioni generali a problemi noti”, consentendo comunque di rispettare in ogni momento le direttive della progettazione ad oggetti al fine di garantire al modularità e la scalabilità del codice. La loro definizione si è raffinata negli anni, attraverso l’esperienza di molti progettisti, che hanno comunque contribuito a stilare le direttive generali, traendo spunto dalla loro esperienza con le tecnologie e i linguaggi Object-Oriented.
La specifica di ogni pattern contiene una descrizione precisa e puntuale del problema affrontato e della soluzione proposta, chiarendo le classi interessate e le collaborazioni tra esse; inoltre, essi sono identificati dal un nome univoco ed esplicativo, permettendo quindi di utilizzarli per la stesura della documentazione, facilitandone la lettura e la comprensione delle soluzioni adottate.
|
|
Breve storia
|
top
|
L’idea di documentare in maniera ‘ufficiale’ delle soluzioni consolidate di progettazione al fi-ne di riutilizzarle nasce da un architetto edile, Christopher Alexander che, alla fine degli anni ’70, fu il primo a proporre l’idea di usare dei ‘pattern’ per progettare le architetture di palazzi ed edifici in genere [1]: egli infatti sosteneva che ‘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 usare la soluzione un milione di volte, senza mai applicarla nella stessa maniera’[1]. Alexander realizzò la sua idea costruendo un ‘Pattern Language’ [2], al fine di aiutare i singoli progettisti a costruire utilizzando l’esperienza collettiva degli altri progettisti e, di conseguenza, focalizzare l’attenzione solo su aspetti essenziali relativi al singolo progetto. Sostanzialmente, ‘Pattern Language’ è una raccolta di p-pattern, ossia Pattern di Progetto, organizzati in uno specifico ordine, e strutturati nel medesimo modo, che consentono, se applicati in sequenza e correttamente, di costruire un edificio completo. 
 Figura 1 - Struttura di un p-pattern Come si può notare in figura, ogni p-pattern è un documento cartaceo strutturato in diverse sezioni: nome, grado di validità, contesto, problema, descrizione, soluzione, diagramma, riferimenti, con ovvio significato delle singole parti. La struttura dei p-Pattern si ritrova in ambito informatico per la prima volta da Erich Gamma, che, nella sua tesi di dottorato [3], presentava un ‘catalogo’ di molti dei pattern esistenti. Successivamente si sono uniti al suo lavoro anche Richard Helm, Ralph Johnson e John Vlissides (in seguito denominati come Gang of Four), ed insieme presentarono un riassunto del catalogo (comunque completo di tutti i pattern) al workshop ad ECOOP ’93 [4]: di lì a breve, il catalogo in forma estesa venne consacrato con l’uscita del libro Design Patterns: Elements of Reusable Object-Oriented Sof-tware [5], che rappresenta ancora oggi una delle pietre miliari della letteratura dedicata alla proget-tazione di sistemi basati sul paradigma ad oggetti.
|
|
Struttura di un pattern
|
top
|
La definizione fornita da Alexander per i p-pattern è stata applicata all’ambito informatico, evidenziando come esso non sia una un blocco statico da applicare in un software sempre nello stes-so modo, ma piuttosto una linea guida generale per la soluzione di problemi di progettazione specifici.
Un Design Pattern è strutturato nel modo seguente:
1. Nome: E’ un nome simbolico di una o due parole che racchiude al suo interno il problema affrontato e la soluzione proposta. Il nome di un pattern è una caratteristica fondamentale anche nel disegno e nella progettazione, in quanto consente di comunicare e documentare ogni scelta di progetto senza scendere nei dettagli implementativi.
2. Problema: Descrive la situazione che l’applicazione del pattern può risolvere, comprensive di condizioni necessarie e propedeutiche all’utilizzo del pattern stesso.
3. Soluzione: In linea con i principi fondamentali dei pattern, la soluzione fornisce uno schema generale e astratto che può essere applicato a contesti diversi, specificando co-munque gli elementi che costituiscono il progetto, le loro responsabilità e collaborazioni.
4. Conseguenze: Descrive l'insieme dei risultati e dei vincoli a cui si va incontro nell'appli-cazione del pattern. Le conseguenze sono fondamentali per poter valutare i vantaggi e gli svantaggi derivanti dall'uso del pattern e per poter eventualmente preferire soluzioni alter-native per la risoluzione del problema.
|
|
Classificazione GRASP e GoF
|
top
|
|
Fino ad ora, si è parlato dei pattern della loro funzione per risolvere i problemi di progettazione. Risulta però necessario evidenziare come un pattern può non solo fornire la soluzione esatta ad un problema, ma può anche costituire una guida su cosa non fare in fase di progettazione: in questo caso, si parla di antipattern. L’antipattern è a tutti gli effetti un “pattern” in quanto è una soluzione progettuale generale a un problema ricorrente ed è costituito da un nome, un problema ed una soluzione, ma, a differenza dai pattern miglioretivi, esso è caratterizzato dal una falsa soluzione, o da una soluzione fondamentalmente negativa. Gli antipattern verranno discussi in seguito, ma per ora è importante conoscerne l’esistenza e la classificazione. In letteratura sono stati documentati moltissimi pattern, ma essi possono essere classificati secondo il loro scopo e ambito di applicazione. Una prima grande distinzione deve essere fatta tra i pattern GRASP e i pattern GoF:
I pattern GRASP (General Responsability Assignment Software Patterns) rappresentano i principi base per l’assegnazione delle responsabilità agli oggetti in relazione al loro ruolo e alle loro collaborazioni e dipendenze: essi costituiscono quindi un aiuto fondamentale nella RDD (Responsability-Driven Development). In questo approccio, gli oggetti sono considerati come entità dotate di responsabilità, intese come ‘contratto o un obbligo di un classificatore’ [7]. Come suggerito in [6], le responsabilità sono fondamentalmente di due tipi :
1. Responsabilità di fare, intesa come dare inizio ad una determinata azione in altri oggetti, creazione di istanze o controllare e coordinare le attività di altri oggetti.
2. Responsabilità di conoscere, intesa come conoscenza di se stesso e degli oggetti correlati, oltre alla conoscenza delle cose che possono essere calcolate o derivate.
In realtà, i GRASP potrebbero non essere considerati veri e propri pattern: essi infatti non presentano la loro struttura caratteristica e non ‘risolvono uno specifico problema. I GRASP possono essere infatti considerati come delle direttive per una buona progettazione ad oggetti, assegnando le responsabilità e le collaborazioni corrette, che permettono, in seguito, di manutenere e ristrutturare il codice senza apportare radicali cambiamenti alla struttura dell’applicazione.
I pattern GoF rappresentano invece soluzioni a problematiche note, applicabili a contesti diversi, al fine di rendere il codice elegante e riusabile. Nel catalogo dei pattern identificati dalla Gang of Four si parla di 23 pattern fondamentali suddivisi nelle seguenti categorie:
1. Pattern Creazionali: forniscono un’astrazione del processo di istanziazione di oggetti, permettendo quindi la resa indipendente di un sistema dalla logica di creazione di oggetti specifici. Di questa cateogoria fanno parte:
 2. Pattern Strutturali: si occupano delle modalità di composizione di classi e oggetti per formare nuove strutture complesse, in grado di fornire delle funzionalità aggiuntive sfruttando la dinamicità della composizione.
3. Pattern Comportamentali: si occupano principalmente dell’assegnazione di responsabilità tra i vari oggetti, utilizzando principalmente il concetto di ereditarietà e di composizione.
I pattern GoF possono essere relazionati secondo lo schema in figura [5]:

Figura 2 - Design Pattern Relationship
|
|
Conclusioni e Bibliografia
|
top
|
|
Conclusioni In questo articolo si è analizzato il concetto generale di pattern ed il perchè essi vengano utilizzati. Si è accennata la fondamentale distinzione tra i pattern e gli antipattern, in relazione al loro scopo e alla loro funzone.
Nei prossimi articoli, si analizzeranno i singoli pattern con esempi di applicazione in codice Java.
Bibliografia
[1] Alexander, Christopher. “The Timeless way of building”, Oxford University Press, New York, 1979.
[2] Alexander Christopher, S. Ishikawa, M. Silverstein, M. Jacobson, I. Fiksdahl-King, S. Angel. “A Pattern Language" Oxford University Press, New York, 1977.
[3] ECOOP '93 Workshop, Kaiserslautern, Germany, July 26-27, 1993.
[4] Gamma, Erich. “Object Oriented Software Development based on ET++: Design Patterns, Classe Library, Tools.” Tesi di Dottorato, University of Zurich, Institut Fur Informatik, 1991.
[5] Gamma, Helm, Johnson, Vlissides. “Design Patterns: Elements of Reusable Object-Oriented Software”, Pearson Education Inc., 1995.
[6] Larman, Craig. “Applying UML and Patterns :An Introduction to Object-Oriented Analysis and Design and the Unified Process”, Pearson Education Inc., 2005.
[7] Object Management Group, 2003. UML 2.0 Superstructure Specification. www.uml.org.
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|