L’ambito di utilizzo dei pattern in informatica è confinato alla progettazione del software, si tratta in sostanza della descrizione di un problema con l’indicazione di una soluzione per risolverlo. I pattern si possono anche applicare a discipline lontane dallo sviluppo software, ma noi approfondiremo l’argomento relativamente a quest’ultimo. I pattern possono essere suddivisi in base a determinate caratteristiche, come ad esempio al periodo di progettazione del software oppure al linguaggio utilizzato, in quest’ultima ottica è particolarmente indicato nei linguaggi di programmazione object-oriented.
La descrizione di un pattern non segue regole molto rigide, basta infatti inserire delle descrizioni testuali magari accompagnate da elementi di tipo grafico come i diagrammi UML. L’aspetto più importante è invece la completezza delle informazioni:
- Nome – necessario per potersi riferire al pattern successivamente
- Descrizione – deve essere il più possibile precisa perché in un pattern la descrizione è più importante della soluzione
- Applicabilità – occorre specificare i vincoli che possono limitare il campo di utilizzo del pattern, ad esempio uno specifico linguaggio di programmazione
- Soluzione – a seconda del tipo di pattern, la soluzione può essere rappresentata da un algoritmo, una porzione di codice o anche da un diagramma di classi
Oltre a queste informazioni fondamentali si possono inserire indicazioni come un elenco di pattern affini oppure degli esempi di codice.
Come dicevamo in un pattern la descrizione del problema è molte volte più importante della soluzione stessa; spesso infatti la conoscenza del problema porta alla soluzione dello stesso. Il pattern una volta riconosciuto è infatti in grado di mettere in evidenza aspetti che potrebbero restare nell’ombra, ovviamente colui che studia il pattern deve essere in grado di leggerlo con esattezza e per questo si deve studiare questa disciplina per poter interpretarli al meglio.
Prendiamo ad esempio il Pattern Iterator che consente di accedere in modo intelligente ad un insieme di dati omogenei. Vediamo il pattern secondo la schematizzazione vista prima:
- Nome: Iterator
- Descrizione: esiste una collezione di elementi ed esistono vari modi per scandirla, si può ad esempio accedere direttamente ad un elemento indicando l’indice, oppure si può passare a quello successivo o precedente. Si desidera applicare la stessa logica di funzionamento a contenitori di tipo diverso come liste, array o tabelle di database.
- Applicabilità: utilizzare questo pattern ha senso se esistono vari modi per accedere agli elementi disponibili all’interno di un contenitore e nascondere la struttura interna dello stesso all’utilizzatore.
- Soluzione: la soluzione proposta per questo pattern può essere realizzata con un linguaggio ad oggetti come C++, C#, Java ed altri, in cui vi sia la possibilità di implementare un’interfaccia all’interno di una classe. Occorrerà infatti definire due interfacce, Iterator e Collection al cui interno verranno implementati i metodi per spostarsi tra un elemento e l’altro, come per esempio: first, prev, next e last, inoltre occorrerà definire un metodo count per avere sempre disponibile il numero di elementi nella collezione. L’interfaccia Collection conterrà un metodo createIterator che permetterà al programmatore di ottenere un Iterator per scandire con i metodi visti prima il contenitore.
Molte librerie utilizzano questo pattern per la gestione dei contenitori o per l’accesso ai database relazionali. Saper interpretare e conoscere i vari pattern è quindi molto importante perché si riesce ad uniformare la programmazione all’interno di diversi linguaggi, che magari avranno dei metodi chiamati in modi diversi, ma con il problema affrontato nella stessa maniera.