Alla scoperta di MVC

Se un programmatore prendesse la briga di scrivere un libro sugli ultimi dieci anni della propria esmodelperienza, verrebbe fuori senza dubbio un mattone dalla notevole mole. In questi anni abbiamo visto andare, passare e tornare di moda tanti concetti e non si contano più le volte che termini come “Applicazione”, “Web”, “Server” e molte altre all’apparenza banali si sono intrecciate. Dopo anni di sviluppo le costanti sono almeno due: il codice tende a crescere e molto spesso (non sempre, ma molto spesso) è scritto malissimo!

Se dieci anni fa già arricciavamo il naso al pensiero di scrivere una pagina PHP che mischiasse tutto, dalla lettura dal database al codice HTML/CSS o di piazzare la logica di un’applicazione Java (o C++ o Visual Basic, ecc) nei gestori dei bottoni, oggi queste pratiche sono inaccettabili probabilmente anche per gli studenti d’informatica alle prime armi. Eppure ci troveremo spesso a fare i conti con pratiche di programmazione orribili, spesso per pura pigrizia o forse paura di alcuni di imparare qualcosa di meglio. In questo articolo userò la terminologia della programmazione a oggetti, ma gli stessi concetti possono essere applicati anche alla programmazione procedurale.

Il primo passo per chi vuole abituarsi a scrivere programmi migliori è sempre lo stesso: separare l’interfaccia dall’implementazione: nella forma più semplice, si scrive una o più classi che definiscono il comportamento dell’applicazione e un’interfaccia che consenta l’interazione dell’utente con essa. Facile a dirsi, eppure a giudicare da certi ammassi informi di codice che si vedono in giro, non lo è nella pratica e, soprattutto, non sempre basta!

La forma da dare al proprio codice è una scelta importante da farsi ancor prima di scrivere una sola istruzione e dipende da quali sono le esigenze. La pena per un approccio alla leggera è ritrovarsi faccia a faccia con la difficoltà di aggiungere nuove funzionalità al nostro programma, che nei casi estremi sfocia in un copia-incolla di funzioni difficilmente riutilizzabili o, peggio, alla condizione nota come “Spaghetti code”, in cui il programma diventa di fatto illeggibile e non più mantenibile. Un codice ben scritto ha almeno le seguenti due caratteristiche:

  1. Separazione dei concetti.
    Avete mai aperto un computer? Noterete senza dubbio che l’alimentatore non scrive dati sull’hard disk e non riceve immagini da Internet. Allo stesso modo, una classe che si occupa di comunicare con un server non è probabilmente una buona candidata al compito di generare immagini. Perché? Perché sono due compiti diversi ed è bene che se ne occupino moduli diversi.
  2. Astrazione.
    Guardando ancora dentro il nostro PC faremo la sensazionale scoperta che disco fisso e lettore CD/DVD sono collegati alla scheda madre con due cavi uguali. La ragione è che la loro interfaccia è astratta. Questo permette al costruttore di progettare moduli che comunichino fra loro senza curarsi troppo di come sono fatti dentro o, in altre parole, della loro implementazione. Più volte possiamo riutilizzare un pezzo di codice, meno ne dovremo scrivere, il che significa meno bug, manutenzione più semplice e facilità di comprensione dei sorgenti, anche per noi stessi quando li rileggeremo dopo mesi.

È tutto? Neanche per sogno, vi basti pensare che persino l’eccesso di astrazione può rendere il vostro programma illeggibile, ma andare più a fondo di così va oltre gli scopi di questo articolo. Agli interessati consiglio di dare uno sguardo al catalogo degli anti-pattern, ai vari tipi di complessità del software (computazione, ciclomatica, ecc) e naturalmente ai vari design pattern.

Uno di questi ultimi è per l’appunto MVC (Modello-Vista-Controllo, anche noto come Model-View-Controller). Si tratta di un pattern architetturale, forse il più noto oggigiorno, che prevede la divisione dell’applicazione in tre componenti fondamentali: Modelli, Viste e Controllori. Scopriamo nel dettaglio di cosa si occupano queste componenti:

  1. Modello
    Il modello (o entità), è il mattone fondamentale della nostra applicazione, che ne contiene i dati e la logica fondamentale. Se scriviamo un’applicazione per la gestione di una biblioteca, le entità saranno ovviamente i libri, gli iscritti ed altre, a seconda dei casi. Un modello meno intuitivo che potrebbe esserci utile nella scrittura di quest’ipotetica applicazione è il prestito, che oltre al codice del libro e dell’iscritto conterrà la data, la durata e, se pensiamo ad un esempio di logica ad esso associata, un calcolo di un’eventuale penale da pagare in caso di ritardo nella restituzione o di danneggiamento.
  2. Vista
    Il compito principale di una vista è consentire all’utente dell’applicazione l’interazione con i modelli, qualunque sia il metodo da noi utilizzato per memorizzarne i dati. La vista presenta dunque i dati del modello, si evolve con esso (nei casi ideali) e ne permette eventualmente la modifica. Si noti come il concetto di “Vista” sia astratto e vagamente discriminatorio. Perché il concetto sia più chiaro, credo sarebbe opportuno sostituire il termine con “Presentazione”. In un dispositivo con soli comandi vocali per esempio non possiamo parlare di vista, ma la funzione di questo componente resta la medesima.
  3. Controllore
    Il controllore riceve i comandi dall’utente e manipola i modelli, modificando di conseguenza la vista. Nella maggior parte delle implementazioni web lato-server di MVC, il controllore si occupa direttamente di generare la vista, passando i dati a un gestore di “template”, come Twig. Da un lato, con questo approccio il controllore riceve i comandi dall’utente (di cui il più semplice sarà la richiesta GET del protocollo HTTP) come dovrebbe, ma dall’altro ciò non applica rigorosamente le specifiche. Tuttavia è semplice e non vanifica lo scopo principale, quello di una netta separazione dei compiti, così possiamo chiudere un occhio!

MVC ci aiuta dunque nella prima delle buone caratteristiche del codice che ho precedentemente elencato: la separazione dei concetti. Sfortunatamente, la seconda dipende essenzialmente dal buon uso che faremo di questa separazione. Alcune librerie possono venire in nostro aiuto forzandoci a scrivere il programma in una certa maniera e fornendoci strumenti riutilizzabili per evitarci parte del lavoro sporco ma, ancora, farne buon uso dipenderà da noi!

È tutto ora? Non proprio. MVC è una specifica, ma la particolare implementazione differisce considerevolmente a seconda della nostra creatività, del linguaggio, dell’ambiente di sviluppo, delle librerie e dell’eventuale framework che utilizziamo. L’abbiamo già visto nella spiegazione del controllore. Un approccio decisamente accademico vuole che la vista sia generata da un solo modello, ma questo è decisamente insolito. Immaginiamo per esempio che l’interfaccia della nostra ormai realistica applicazione per la biblioteca includa statistiche sui prestiti dei libri e degli iscritti a ogni schermata. Questo implica l’uso di vari modelli e ciò causa non poche crisi esistenziali ai neofiti di MVC. Per la cronaca, molti alleviano il proprio senso di colpa introducendo il concetto di “vista parziale”, del quale non mi occuperò qui. Inoltre non tutte le parti del nostro programma sono necessariamente modelli, viste o controllori, specialmente se il nostro programma è molto complesso e ad un certo punto sentiamo la necessità di spostare il nostro codice dai modelli per evitare che questo li faccia crescere a dismisura (in gergo si parla di “modelli grassi”) e che divenga difficilmente riutilizzabile.

In effetti da specifiche così semplici nasce un mondo di ricerche di soluzioni, decine di approcci diversi e molte discussioni. Tornerò senza dubbio ad occuparmi dell’argomento. Quando ho iniziato a scrivere quest’articolo ho iniziato a preparare anche un esempio didattico, ma come accade spesso, mi sono lasciato prendere la mano ed esso si è evoluto in un vero e proprio framework PHP che sto utilizzando per siti web esistenti e che è divenuto il banco di prova per alcune delle mie idee. Anch’esso sarà pubblicato ed illustrato a tempo debito. Per il momento, spero che questa modesta spiegazione sia chiara ed utile.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *