Con la release delle versione 5 di Laravel e la rinnovata struttura delle sue directory si segna una chiara svolta nella metodologia di sviluppo del nostro software.
Otwell stesso lancia un messaggio allo sviluppatore PHP di oggi, e lo incoraggia a sfruttare il namespacing nelle proprie classi, a modularizzare la business logic, scrivere codice riutilizzabile e seguire i concetti base della programmazione OOP. Per chi inizia a seguire questa strada, lo sviluppo di un modulo software può risultare problematico, e portare spesso a nuovi problemi di progettazione che, per scadenze imminenti o poco tempo a disposizione, porta inevitabilmente all’uso di bad practice e di codice poco elegante e poco testabile.
È bene però porsi un assunto: per quanto lo sviluppo software sia vario, molti dei problemi di progettazione che incontreremo lungo il nostro cammino sono già stati affrontati da migliaia di sviluppatori prima di noi, e questi a loro volta hanno già trovato delle soluzioni efficienti al vostro comune problema. La domanda che alcuni di questi sviluppatori si sono posti per te è: come beneficiare di questa esperienza per permettere alle nuove generazioni di ottimizzare la propria codebase?
È in questo contesto che nascono i Design Pattern.
Partendo da una definizione formale:
Un design pattern, nella sua essenza, descrive una soluzione generale a un problema di progettazione ricorrente.
Ciascun design pattern, come vedremo in questa serie, astrae gli aspetti principali della struttura utilizzata per risolvere una certa categoria di problemi e identifica classi e istanze partecipanti e la relativa distribuzione delle responsabilità, descrivendo quando e come un pattern può essere applicato. In maniera più informale, un design pattern definisce la soluzione allo stato dell’arte per risolvere una certa classe di problemi.
Un Po’ di Storia
Il concetto dei Design Pattern di per sé non è moderno, ed è possibile far risalire la sua origine al 1977 con il saggio “A Pattern Language” dell’architetto Christopher Alexander. Nel 1995, la Gang Of Four (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) avrebbe portato i concetti dei design pattern di Alexander al mondo dello sviluppo software, con il libro “Design Pattern – Elementi per il riuso di software ad oggetti” (altre informazioni qui). Il successo di questo approccio fu enorme, al punto che già dai primi del 2000 era possibile trovare questi concetti applicati ai linguaggi C++, Java e C#.
Design Pattern e PHP
Già dalla versione 5 del linguaggio, PHP fornisce una serie di nuove funzionalità dedicate all’object oriented, dandoti la possibilità di implementare i design pattern per migliorare il design del tuo codice. In questo modo, ti renderai conto di come tutto diverrà più leggibile, più manutenibile e più robusto in modo tale da assorbire meglio i cambiamenti. Questi schemi risolvono alcuni generici o concreti problemi di progettazione e rendono il design dei moduli object oriented più flessibile, robusto ed elegante.
Dai feedback di numerosi sviluppatori si evince un altro fatto importante. Questi, nel loro quotidiano, hanno per anni utilizzato i design pattern senza nemmeno conoscerli, in maniera del tutto inconsapevole. Questo ci porta ad una nuova tesi: la nostra mente è già predisposta per accettare questi meccanismi.
Per fare un’analogia con le tue esperienze: quante volte ti è capitato di risolvere un problema e trovare familiare la soluzione usata? Come se in un altro periodo ti fosse già capitato di effettuare un certo ragionamento e arrivare alla stessa medesima soluzione. Nel loro profondo, i design pattern sfruttano proprio questo fenomeno, rendendo semplice il riuso di architetture di design vincenti e efficaci, e generando uno standard riconoscibile universalmente. In definitiva, i design pattern aiutano i “designer” a scegliere velocemente la strada giusta da seguire.
Solid Principle & Design Pattern
Tra le motivazioni che dovrebbero spingerti allo studio approfondito dei DP, ecco a mio parere la più importante di tutte:
I design pattern invitano lo sviluppatore a rispettare le linee guida dei principi SOLID della programmazione orientata agli oggetti.
Mentre analizzeremo singolarmente ciascun pattern, vedremo infatti come l’obiettivo costante sarà quello di eliminare la duplicazione di codice, minimizzare il refactoring e seguire i concetti dello sviluppo Agile del software.
Classificazione dei Design Pattern
Per presentare ciascuno schema, useremo la medesima classificazione presentata dalla Gang of Four, suddividendo i Design Pattern in 3 categorie principali, quelle dei pattern creazionali, strutturali e comportamentali.
- Creazionali: si occupano dei meccanismi di creazione degli oggetti, cercando di istanziare oggetti nel modo più adatto alla situazione.
- Strutturali: facilitano la progettazione individuando un modo semplice per realizzare relazioni tra le classi.
- Comportamentali: identificano i modelli di comunicazione comuni tra oggetti e focalizzano l’attenzione sul comportamento degli oggetti.
Ciascun pattern, inoltre, verrà classificato in base al proprio scope, distinguendo:
- Class Pattern: si occupano delle relazioni fra le classi e le loro sottoclassi. Queste relazioni vengono stabilite attraverso l’ereditarietà e pertanto sono già fissate al runtime.
- Object Pattern: si occupano delle relazioni fra gli oggetti, che possono cambiare al runtime e sono quindi più dinamiche.
Scegliere il Pattern Adatto
Uno dei meccanismi più difficili da comprendere durante l’apprendimento dei design pattern è capire, di volta in volta, quale schema meglio si presta alla risoluzione di un problema. Per aiutarci in questa scelta, basti pensare che ogni pattern è caratterizzato da 4 componenti chiave:
- Il suo nome;
- Il problema da risolvere, ovvero sotto quali circostanze può essere usato un particolare pattern;
- La metodologia risolutiva, che non è costituita da codice ma fornisce abbastanza informazioni per generarlo;
- Le conseguenze, ovvero pro e contro dell’utilizzo di un certo pattern;
L’ultimo punto è secondo me fondamentale, poiché identificando le conseguenze di un certo pattern avrai abbastanza elementi per capire se è adatto o meno alla tua situazione.
Questo ti permette quindi di affermare che non esistono soluzioni perfette e universalmente adatte a qualsiasi situazione ma prima di scegliere il giusto pattern da usare devi valutare bene il contesto in cui ti trovi.
Non tutti gli approcci standard sono perfetti per ogni situazione, è tuo compito valutare i pro e contro di ogni approccio.
Nel Prossimo Episodio
Il primo capitolo di questa serie introdurrà i design pattern creazionali e, in particolare, l’Abstract Factory Pattern. Vedrai quali vantaggi e svantaggi vi sono nell’istanziare un oggetto a partire da una famiglia astratta di oggetti senza far riferimento alle relative classi concrete. Vedrai inoltre come questo tipo di pattern può essere utilizzato in Laravel 5.
Il Tuo Parere
Durante la stesura di questa serie, penso sia fondamentale capire quali siano le tue necessità e quali difficoltà trova la community nell’applicare quotidianamente questi concetti, quindi ogni feedback/dubbio è ben accetto!