|
Introduzione
I
Patterns per lo sviluppo del software non sono semplicemente
suggerimenti per risolvere particolari problemi, ma
una vera e propria disciplina scientifica che ha lo
scopo di aiutare gli sviluppatori del software a risolvere
problemi ricorrenti che si incontrano nella fase di
analisi e codifica del software.
Al fine di raggiungere questo scopo, e' necessario definire
formalmente un linguaggio comune per comunicare esperienze,
per definire problemi e la loro soluzione. Questo approccio
formale permette, quindi, di acquisire quella conoscenza
profonda del problema e giustificare una soluzione piuttosto
che un'altra.
Altro punto importante, quindi, e' dire che questa disciplina
non fornisce semplicemente una soluzione al problema,
ma fornisce quella "ottima". I Design Patterns
non si focalizzeranno, quindi, sulla tecnologia, quanto
sulla creazione di una cultura per la documentazione
ed il supporto di un solido approccio alle architetture
ed al design.
Ognuno
di noi puo' definire un suo patterns, l'importante e'
seguire delle linee guida che sono accettate dalla comunita'
scientifica "Pattern Community" e di cui parleremo
successivamente.
L'origine dei Patterns
Il
termine Pattern fu coniato da alcuni lavori dell'architetto
Christopher Alexander ed applicato allo sviluppo di
piani urbani ed alle architetture di costruzioni urbane.
Un esempio di lavoro di Alexander e' "A Pattern
Language: Towns, Buildings, Constructions (Oxford University
Press, 1977).
Lo
studio di Alexander sui patterns aveva lo scopo di dimostrare
che l'archittettura del tempo era inadeguata per incontrare
la reale domanda del momento e i requisiti degli utenti,
della societa' e degli individui, e falliva nel realizzare
lo scopo ultimo di ogni attivita' ingenieristica e di
design: migliorare le condizioni umane.
Anche se il lavoro di Alexander e' esclusivamente un
lavoro di architettura e di pianificazione urbana, I
concetti da lui sviluppati possono essere applicabili
ad altre discipline, come lo sviluppo del software.
Alexander
propose un paradigma per l'architettura che venne poi
ripreso ed adattato da Ward Cunningham e Kent Beck nel
1987, mentre si trovavano a lavorare con Smalltalk nel
creare interfacce utenti. Cunningham e Kent svilupparono
cinque pattern per comunicare concetti a programmatori
che si avvicinavano per la prima volta allo sviluppo
con Smalltalk. Il loro lavoro venne presentato a OOPSLA
'87 nel documento: "Using Pattern Languages for
Object-Oriented Programs".
Successivamente
il concetto di Pattern nel mondo dello sviluppo del
software si e' consolidato e con l'uscita del lavoro
della "Gang of Four" dal titolo "Design
Patterns: Elements of Reusable Object-Oriented Software"
il termine Patterns e' entrato ufficialmente nella letteratura
della Computer Science con un proprio significato.
Cos'e'
quindi un Pattern?
Dopo
questa introduzione non voglio dimenticare di dare una
definizione formale al Pattern:
"Un
Pattern e' la descrizione chiara e formale di un problema
(o una famiglia di problemi) ricorrenti, e della sua
risoluzione. Questa descrizione ha lo scopo di catturare
l'essenza stessa del problema all'interno di certi contesti.
La comprensione di tali problemi e' necessaria per la
apprezzare la soluzione proposta. Tale soluzione puo'
essere non-ottimale se il problema viene estrapolato
dal contesto considerato."
I
problemi descritti nei Patterns sono ricorrenti, nel
senso che ogni sviluppatore ha incontrato lo stesso
problema nel passato e lo incontrera' nuovamente nel
futuro.
E'
la stessa natura "ricorrente" del problema
che fa del Pattern un formidabile strumento di design
e di architettura: creare un Pattern significa riutilizzare
e condividere l'esperienza di qualche altro sviluppatore
che ha dovuto affrontare gli stessi ostacoli logici
e architetturali.
Punto
fondamentale del Pattern e', quindi, la capacita' di
documentare tali problemi e le relative soluzioni. Questo
viene ottenuto attraverso una serie ben definita di
passi che possiamo riassumere nel seguente schema:
-
La motivazione o contesto in cui il pattern viene
applicato
- Prerequisiti
che devono essere soddisfatti per l'applicazione del
pattern
- Una
descrizione della struttura del programma che il pattern
andra' a definire
- Una
lista di partecipanti necessari alla completezza del
pattern
- Conseguenze
nell'uso del pattern sia dal punto di vista di vantaggi
che svantaggi
- Fornire
almeno un esempio nell'uso del pattern.
E'
chiaro, quindi, che un pattern include una descrizione
generale della descrizione di un problema ricorrente
con vari vincoli ed obiettivi. In ogni caso un pattern
non si limita ad identificare una soluzione, ma anche
a spiegare perche' questa soluzione e' necessaria.
Ultimamente
il termine "Pattern" e' un po' alla moda,
e sembra che tutto debba essere legato ad essi. Questo
ha generato molte delusioni in molte persone che vedevano
in essi la soluzione di ogni problema ed, in qualche
modo, delegittimato coloro che, nella patterns community,
stanno facendo uno sforzo reale nel documentare patterns
"veri".
Detto
questo e' importante dire che non tutte le soluzioni,
algoritmi o best practice sono descritte nei patterns.
Anche se il problema che si sta studiando sembra avere
tutti I requisiti per essere identificato come pattern,
non dovrebbe essere considerato tale, fino a quando
possa essere verificata la sua natura ricorrente.
L'azione
di documentare un pattern valido puo' essere incredibilmente
difficile. Un pattern per essere valido deve soddisfare
queste linee guida:
-
Risolvere un problema: Patterns identificano soluzioni,
non principi astratti o strategie.
- E'
un concetto solido: La soluzione indicata nel pattern
deve essere solida e ben dimostrata: non teorie o
speculazioni.
- La
soluzione non e' ovvia: Molte tecniche di problem-solving
tendono a derivare soluzioni da principi. Nei pattern
la soluzione e' generata indirettamente, attraverso
un approccio formale.
- Un
Pattern descrive relazioni: Un pattern non descrive
semplicemente dei moduli, quanto profonde strutture
e funzionalita' di un sistema.
Ricordate
inoltre che il fatto di avere una soluzione che non
sia un pattern, non significa che questa sia una soluzione
non valida o banale. Il fatto di avere un pattern implica
una soluzione ottima, ma il contrario non e' vero, cioe'
si puo' avere una soluzione ottima senza che questa
sia un pattern. Quindi e' bene considerare con grande
rispetto I patterns, ma non cosiderarli come una legge
assoluta.
Se
un pattern descrive una "Best Practice" allora
un "Anti-Pattern" descrive una "Bad Practice".
Gli anti-pattern proposti da Andrew Koening non saranno
soggetto di questo articolo e lascio a voi ogni giudizio
a riguardo.
Nella
letteratura, sono stati sviluppati patterns in diversi
settori. Abbiamo cosi Design Patterns, Analysis Patterns
ed anche Organizational Patterns.
Probabilmente
i Design Patterns sono quelli che vi sono piu' a cuore,
e che vengono definiti come "la descrizione di
oggetti e classi comunicanti che hanno lo scopo di risolvere
generali problemi di design in un particolare contesto".
In
questo tipo di patterns vengono identificate tutte le
classi partecipanti, le loro istanze, i loro ruoli e
la distribuzione delle loro responsabilita'. Ognuno
dei pattern si concentrera' su particolari problemi
di design Object-Oriented. Verra' descritto quando questo
pattern viene applicato oppure quando non e' assolutamente
il caso di farlo.
Elementi
di un Pattern
Per
quanto riguarda il formato utilizzato nella descrizione
un pattern, potrete trovare alcune differenze tra i
diversi autori. In ogni caso, c'e' un consenso comune
sugli elementi che devono essere presenti nella presentazione
formale di un pattern:
-
Nome: deve essere un nome che abbia senso.
Questo permette agli sviluppatori di utilizzare un
nome come riferimento al pattern e al concetto e struttura
che esso descrive. Puo' accadere che uno spesso pattern
possa essere conosciuto con nomi diversi ed in questo
caso e' bene riportare anche una lista di nomi sotto
cui il pattern e' conosciuto.
-
Problema: Una chiara descrizione del problema
che il pattern si trova ad affrontare: gli obiettivi
che si vogliono raggiungere all'interno di un particolare
contesto (se presente).
-
Contesto: Le precondizioni sotto le quali il
problema e la sua soluzione sembrano ricorrere, e
per le quali la soluzione e' desiderabile. Il contesto
puo' essere pensato come la configurazione iniziale
del sistema prima dell'applicazione del pattern.
-
Vincoli: Una descrizione dei vincoli presenti
nel contesto e di come questi interagiscono tra loro.
I vincoli rivelano le scelte che dobbiamo considerare
nello scenario che essi descrivono.
-
Soluzione: Questo spesso equivale a dare istruzioni
su come ottenere il risultato finale. Nell'offrire
la soluzione e' possibile utilizzare qualsiasi media,
come figure e diagrammi, che identificano la struttura
del pattern, gli attori e la collaborazione tra le
parti, allo scopo di visualizzare come il problema
e' risolto. La soluzione non dovrebbe contenere soltanto
strutture statiche, ma anche comportamenti dinamici.
- Esempi:
Uno o piu' esempi devono accompagnare la descrizione
del pattern. In questi esempi deve essere chiaro qualche
contesto iniziale viene utilizzato, come il pattern
viene utilizzato ed, eventualmente, come il contesto
viene modificato dal pattern stesso. Gli esempi aiutano
il lettore a comprendere, in modo profondo, l'uso
del pattern e la sua applicabilita'.
- Contesto
Finale: Lo stato o configurazione del sistema
dopo che il pattern e' stato applicato, includendo
le conseguenze (sia positive che negative) nell'applicazione
del pattern, oppure eventuali problemi che possono
crearsi nel nuovo contesto.
- Referimenti
ad altri pattern: Relazioni tra il pattern che
si sta descrivendo ed altri pattern utilizzati nel
sistema. Se esistono relazioni tra diversi pattern
e' possibile che questi condividano lo stesso gruppo
di vincoli oppure il contesto di applicabilita'.
- Usi
conosciuti:
descrivere sistemi che utilizzano questo pattern e
come esso e' stato applicato per risolvere il problema
iniziale. Questo aspetto e' molto importante perche'
aiuta a dimostrare la soluzione del pattern e a provarne
la sua natura ricorrente.
Anche
se non obbligatorio, molti pattern iniziano con un Abstract
utilizzato come un'introduzione o come sintesi del problema
che ci stiamo accingendo a descrivere. Inoltre un pattern
dovrebbe esplicitamente descrivere il suo audience e
le conoscenze di base che il lettore deve avere.
Concludo questo articolo con la descrizione di un pattern
molto semplice, ma molto importante nelle architetture
di sistemi: il Singleton.
Singleton
Problema
Questo
pattern si applica in tutte quelle situazioni in cui
esiste la necessita' di avere una singola istanza di
una determinata classe.
Spesso viene lasciata al programmatore la responsabilita'
di assicurare l'esistenza di una sola istanza di una
classe con la conseguente possibilita' di errori e bug
di sistema.
Un
importante aspetto di questo pattern e' il modo in cui
questa singola instanza viene messa a disposizione di
ogni oggetto che ne faccia richiesta. Dalla responsabilita'
del programmatore si passa al comportamento di una classe:
e' la classe stessa (behaviour) che garantisce l'esistenza
di una singola istanza.
Classi
Questo
pattern viene implementato attraverso una sola classe.
Di seguito viene riportato il diagramma di come il singleton
e' stato concepito:

Figura
1 - Singleton Cloud
Caratteristica
principale e' l'uso di un costruttore privato (e' questo
che garantisce la singola istanza) e di un metodo publico
e statico getIstance(). La singola istanza viene mantenuto
attraverso l'uso di una variable privata e statica istance.
Vantaggi
Assoluto
controllo sull'istanza singola della classe. Quando
questo pattern viene implementato come raccomandato,
la class singleton controllera' direttamente la creazione
delle sue istanze, attraverso il costruttore privato.
Questo solleva il programmatore dalla responsabilita'
di assicurare l'esistenza di una sola istanza.
Esempi
Ecco
un esempio di singleton scritto in Java:
public
class Singleton{
private static Singleton instance=null;
private Singleton()
{
inizializzazioni
}
public static Singleton getInstance()
{
if (instance==null)
{
instance=new Singleton();
}
return instance;
}
Altri metodi
}
Usi
Conosciuti
Esempi
d'uso di questo pattern possono essere:
-
Connecion Pooling
- Generazione
di SID globali
- DesktopView
Pattern
Relativi
Instance
Creation
Conclusioni
Come
abbiamo visto I Patterns sono catalogabili per aree
di interesse. Possiamo trovare patterns per sistemi
real time, o come nel nostro caso, pattern applicabili
allo sviluppo di applicazioni basate su tecnologia J2EE.
Conoscere I patterns significa avere una profonda conoscenza
sulle problematiche legate all'architettura di sistemi
e di design; conoscere I patterns significa conoscere
la soluzione a problemi ricorrenti, che sicuramente
incontreremo nella nostra vita professionale.
Avere un'esposizione ai pattern e' fondamentale per
gli architetti di sistemi e designers e aggiungo di
avere sempre un aspetto critico verso I patterns perche',
come abbiamo visto, essi offrono una soluzione ottima
che dipende dal contesto. Se il contesto cambia, anche
la soluzione puo' cambiare, invalidando il pattern stesso.
Se questo e' il caso, invito tutti ad offrire una soluzione
valida e di sottoporla alla Patterns Community come
momento di accettazione formale, e dare, cosi', il vostro
contributo al mondo degli sviluppatori di software e
degli architetti di sistemi.
Reference
[A
Pattern Language] - Oxford University Press, 1977.
[Patterns] - Richard Helm e Ralph Johnson, 1998
[Essential Concept and Terminology] - Brad Appleton,
2000
[Singleton] - Erich Gamma, 1995
Giancarlo
Crocetti si e' laureato in Scienze dell'informazione
all'universita' "La Sapienza" di Roma per
poi conquistare il Master in Computer Science alla Rutgers
University del New Jersey nel 1998. Dal 1996 vive a
New York dove lavora come consulente per importanti
aziende ed enti governativi come: Computer Science Corporation,
United Nations, Merrill Lynch, Lockheed Martin e per
il governo degli Stati Uniti.
Da piu' di quattro anni il 60% dei sistemi da lui architettati
e sviluppati vengono implementati utilizzando tecnologie
Java. Nel 2000 ha creato la propria azienda Nous USA
inc., che offre servizi di consulenza e di training
concentrate soprattutto su tecnologie Java.
|