Discutere di pattern: i meta-patterns
Prima di iniziare a parlare dei principali pattern che un informatico dovrebbe conoscere, possiamo chiederci come possiamo parlare di pattern: semplice, con dei meta-patterns, pattern con cui costruire altri pattern!
Nello specifico, i meta-patterns identificano due elementi base su cui ragionare quando si trattano i pattern:
-
HookMethod: un “metodo astratto” che, implementato, determina il comportamento specifico nelle sottoclassi; è il punto caldo su cui interveniamo per adattare lo schema alla situazione.
-
TemplateMethod: consiste in una struttura generale che contiene delle parti cambiabili, ovvero gli hook. Quindi è metodo che coordina generalmente più HookMethod per realizzare il design voluto; è l’elemento freddo di invariabilità del pattern che ne realizza la rigida struttura.
Un esempio potrebbe essere una funzione di ordinamento, dove c’è uno scheletro generale dell’algoritmo (template) al cui interno non viene specificato il modo in cui avviene la comparazione tra elementi. Customizzando questa comparazione si realizzano gli hook, che se inseriti all’interno del templete rendono l’algoritmo funzionante.
Ovviamente i metodi template devono avere un modo per accedere ai metodi hook se intendono utilizzarli per realizzare i pattern. Tale collegamento può essere fatto in tre modi differenti:
- Unification: hook e template si trovano nella stessa classe astratta, classe da cui erediteranno le classi concrete per implementare i metodi hook e, di conseguenza, il pattern; i metodi template sono invece già implementati in quanto la loro struttura non si deve adattare alla specifica applicazione. Un esempio è presente nell’interfaccia Iterable, che richiede l’implementazione dei metodi next e hasNext, inoltre è presente anche un metodo di default chiamato forEach che permette di chiamare next fintantochè hasNext restituisce true. Tutti questi metodi si trovano nella stessa interfaccia; la struttura generale che vale sempre è data dal metodo di default forEach, e gli hook invece sono next e hasNext, che se forniti permettono a forEach di funzionare.
- Connection: hook e template sono in classi separate, indicate rispettivamente come hook class (astratta) e template class (concreta, che rimane), collegate tra di loro da un’aggregazione: la classe template contiene cioè un’istanza della classe hook, in realtà un’istanza della classe concreta che realizza i metodi hook usati per implementare il pattern (in base all’implementazione dell’hook utilizzata il comportamento generale cambia).
- Recursive connection: come nel caso precedente hook e template sono in classi separate, ma oltre all’aggregazione tali classi sono qui legate anche da una relazione di generalizzazione: la classe template è una hook class (questo tipo di relazione viene adottato dai pattern decorator e composit). Le relazioni tra le due classi sono doppie e magari ricorsive.
Vedremo a quale meta-pattern aderiranno i pattern che vediamo. A tal proposito,i pattern che vedremo fanno parte dei cosiddetti “Gang Of Four patterns”, una serie di 23 pattern definiti da Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, ormai molti anni fa ma ancora attuali. Oltre ad averli definiti li hanno divisi in tre categorie:
- Creazionali: legati alla creazione di oggetti
- Comportamentali: legati all’interazione tra oggetti
- Strutturali: legati alla composizioni di classi e oggetti