Javascript OOP con AMD e RequireJS

L’abbondanza di nuovo materiale reperibile in rete in tema di “modularità” delle applicazioni Javascript, tipicamente per quanto riguarda applicazioni web particolarmente“client-side” (o addirittura SPA) ma anche per quanto concerne applicazioni NodeJs, unitamente ad iniziative quali TypeScript, dimostrano il bisogno che la moderna comunità degli sviluppatori ha di metodologie e best practices finalizzate alla riduzione del rischio di “spaghetti-code” nella creazione di progetti Javascript complessi, quali quelli che quotidianamente vengono affrontati da chi utilizza questo linguaggio per professione.

Senza addentrarci in temi troppo “accademici”, credo non si possa negare che gli elementi più critici in tal senso sono due:

  • Scarsa propensione all’OOP
  • Difficoltà nella gestione delle dipendenze

Quanto al primo punto, in realtà non si può dire che Javascript non sia un linguaggio object-oriented, anzi al contrario lo è, ed addirittura molto più di altri (anche le funzioni sono oggetti, ad esempio); quello che con più esattezza motiva la scarsa propensione ad essere utilizzato come linguaggio adatto all’OOP è semmai la sua peculiarità ad essere più “object-oriented” che “class-oriented” (o “type-oriented”), cosa che di fatto mette a disagio chi ha più dimestichezza con linguaggi quali C++, Java e C#, caratterizzati da un paradigma effettivamente molto differente.

In merito al secondo punto, se facciamo ad esempio riferimento ad una applicazione web più o meno tipica, non possiamo non notare come l’inclusione di 10-15 script “*.js” fatta da parte dei vari frammenti di markup HTML che popolano ciascuna pagina/vista dell’applicazione ha l’effetto di “inquinare” (non a caso si parla di “namespace pollution”) lo spazio in cui operano gli oggetti attivi all’interno dell’engine (che sia quello interno al browser o quello definito in nodejs) che sta eseguendo la nostra applicazione, senza considerare l’intricato rapporto di dipendenze che molto spesso esiste tra gli script in questione.

Sebbene non mi senta di dire che si tratti della soluzione “ottima” o “definitiva”, ho trovato particolarmente efficace la soluzione illustrata di seguito, in cui il primo punto critico è affrontato utilizzando un pattern per la traduzione dei concetti tipici di un linguaggio OOP quale Java, C++ o C#, mentre il secondo viene sostanzialmente risolto mediante l’adozione del cosiddetto “Module-pattern” (nella “accezione” AMD, più precisamente), reso per l’occasione meno “complicato” dall’utilizzo del framework RequireJS, che sta di fatto diventando uno standard infrastrutturale anche in molti framework più “verticali”.

Per rendere l’illustrazione di questo approccio più eloquente possibile, direi di utilizzare l’esempio che segue, costituito dalla seguente struttura di file:

  • default.htm
  • scripts (dir)
    • scripts/main.js
    • scripts/person.js
    • scripts/student.js
    • scripts/require.js

Il file default.htm, un po’ scarso nella sua espressione puramente UI dal momento che tutto l’output del demo si svolge all’interno della console del browser, è il seguente, in cui è evidenziata la parte di dichiarazione delle dipendenze gestita da RequireJS:

Lo script person.js è il seguente:

Mentre Student.js è il seguente:

Per verificare il funzionamento del tutto possiamo utilizzare un main.js come quello che segue:

Così facendo, dovremmo ottenere un output di questo tipo:

Per approfondimenti:

https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript

http://phrogz.net/JS/classes/OOPinJS.html

http://phrogz.net/JS/classes/OOPinJS2.html

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

https://github.com/amdjs/amdjs-api/wiki/AMD

http://requirejs.org/docs/start.html

29/07/2014
Tags: , , ,
Categorie: PostSviluppo
Autore: Lorenzo Maiorfi

l’abbondanza di strumenti di modularità JS mostra il bisogno che la moderna comunità degli sviluppatori ha di metodologie e best practices finalizzate alla riduzione del rischio di “spaghetti-code” nella creazione di progetti Javascript complessi


Support