Architettura MVC

Man mano che i browser moderni diventano più potenti grazie a funzionalità avanzate, la creazione di applicazioni web complete in JavaScript non è solo fattibile, ma sempre più popolare. In base alle tendenze su HTTP Archive, le dimensioni del codice JavaScript di cui è stato eseguito il deployment sono aumentate del 45% nel corso dell'anno.

Dimensioni di trasferimento JS e richieste JS

Con l'aumento della popolarità di JavaScript, le nostre applicazioni lato client sono molto più complesse di prima. Lo sviluppo di applicazioni richiede la collaborazione di più sviluppatori. Scrivere codice mantenibile e riutilizzabile è fondamentale nella nuova era delle app web. L'app Chrome, con le sue ricche funzionalità lato client, non fa eccezione.

I pattern di progettazione sono importanti per scrivere codice gestibile e riutilizzabile. Un pattern è una soluzione riutilizzabile che può essere applicata a problemi comuni nella progettazione del software, nel nostro caso la scrittura di app di Chrome. Consigliamo agli sviluppatori di disaccoppiare l'app in una serie di componenti indipendenti seguendo il pattern MVC.

Negli ultimi anni sono stati sviluppati una serie di framework MVC JavaScript, come backbone.js, ember.js, AngularJS, Sencha, Kendo UI e altri ancora. Sebbene abbiano tutti vantaggi esclusivi, ognuno segue una qualche forma di pattern MVC con l'obiettivo di incoraggiare gli sviluppatori a scrivere codice JavaScript più strutturato.

Panoramica del pattern MVC

MVC offre vantaggi architetturali rispetto a JavaScript standard: ti consente di scrivere codice in modo più organizzato e, di conseguenza, di più gestibile. Questo pattern è stato usato e ampiamente testato su più linguaggi e su generazioni di programmatori.

MVC è composto da tre componenti:

controller-visualizzazione-modello

Modello

Il modello è il luogo in cui vengono archiviati gli oggetti dati dell'applicazione. Il modello non sa nulla su viste e controller. Quando un modello cambia, in genere avvisa gli osservatori che si è verificata una modifica.

Per capire meglio questo concetto, usiamo l'app Elenco attività, una semplice app web di una pagina che monitora l'elenco delle attività.

controller-visualizzazione-modello

Il modello qui rappresenta gli attributi associati a ogni elemento di attività, come descrizione e stato. Quando viene creato un nuovo elemento di promemoria, questo viene archiviato in un'istanza del modello.

Visualizza

La visualizzazione è ciò che viene presentato agli utenti e il modo in cui gli utenti interagiscono con l'app. La visualizzazione è realizzata con HTML, CSS, JavaScript e spesso modelli. Questa parte dell'app Chrome ha accesso al DOM.

Ad esempio, nell'app web dell'elenco di cose da fare sopra riportato, puoi creare una visualizzazione che presenti in modo appropriato l'elenco di cose da fare agli utenti. Gli utenti possono anche inserire un nuovo elemento di promemoria tramite un formato di input; tuttavia, la vista non sa come aggiornare il modello perché è questo il compito del controller.

Controller

Il controller è il responsabile delle decisioni e il collante tra il modello e la vista. Il controller aggiorna la visualizzazione quando il modello cambia. Inoltre, aggiunge listener di eventi alla visualizzazione e aggiorna il modello quando l'utente manipola la visualizzazione.

Nell'app web dell'elenco di cose da fare, quando l'utente controlla che un elemento è stato completato, il clic viene inoltrato al controller. Il controller modifica il modello per contrassegnare l'elemento come completato. Se i dati devono essere persistenti, viene anche eseguito un salvataggio asincrono sul server. Nello sviluppo di app web lato client avanzate, ad esempio le app di Chrome, è fondamentale anche mantenere i dati persistenti nello spazio di archiviazione locale. In questo caso, il controller gestisce anche il salvataggio dei dati nello spazio di archiviazione lato client, ad esempio l'API FileSystem.

Esistono alcune varianti del pattern di progettazione MVC, ad esempio MVP (Model-View-Presenter) e MVVP(Model-View-ViewModel). Anche con il cosiddetto modello di progettazione MVC, esistono alcune variazioni tra il modello MVC tradizionale e l'interpretazione moderna in vari linguaggi di programmazione. Ad esempio, per alcuni framework basati su MVC la vista osserva le modifiche nei modelli, mentre altri consentono al controller di gestire l'aggiornamento della vista. Questo articolo non si concentra sul confronto tra varie implementazioni, ma piuttosto sulla separazione delle preoccupazioni e sulla sua importanza nella scrittura di app web moderne.

Se ti interessa saperne di più, ti consigliamo il libro online di Addy Osmani: Learning JavaScript Design Patterns.

Riassumendo, il pattern MVC offre modularità agli sviluppatori di applicazioni e consente di:

  • Codice riutilizzabile ed estendibile.
  • Separazione della logica di visualizzazione dalla logica di business.
  • Consenti il lavoro simultaneo tra sviluppatori responsabili di diversi componenti (ad esempio il livello UI e la logica di base).
  • Più facile da gestire.

Pattern di persistenza MVC

Esistono molti modi diversi di implementare la persistenza con un framework MVC, ognuno con compromessi diversi. Quando scrivi le app di Chrome, scegli i framework con MVC e i pattern di persistenza adatti alle tue esigenze dell'applicazione.

Il modello esegue la propria persistenza - Pattern ActiveRecord

Popolare in framework lato server come Ruby on Rails e in framework lato client come Backbone.js e ember.js, il pattern ActiveRecord è responsabile della persistenza del modello stesso e viene generalmente implementato tramite l'API JSON.

Una versione leggermente diversa rispetto alla gestione della persistenza da parte di un modello è introdurre un concetto separato di API Store e Adapter. Store, Modello e Adattatore (in alcuni framework è chiamato proxy) funzionano mano a mano. L'archiviazione è il repository che contiene i modelli caricati e fornisce anche funzioni come la creazione, l'esecuzione di query e l'applicazione di filtri alle istanze dei modelli contenute al suo interno.

Un adattatore, o un proxy, riceve le richieste da un archivio e le traduce in azioni appropriate da intraprendere rispetto al livello dati permanente (ad esempio l'API JSON). Questo aspetto è interessante nel moderno design delle app web, perché spesso interagisci con più di un livello dati persistente, ad esempio un server remoto e lo spazio di archiviazione locale del browser. Le app di Chrome forniscono sia l'API Chrome Storage sia l'API HTML 5 fileSystem per l'archiviazione lato client.

Vantaggi:

  • Semplice da usare e da capire.

Contro:

  • Difficile da testare poiché il livello di persistenza è "basato" nella gerarchia degli oggetti.
  • La presenza di oggetti diversi che utilizzano archivi permanenti diversi è difficile (ad esempio, API FileSystem, indexDB o lato server).
  • Il riutilizzo del modello in altre applicazioni potrebbe creare conflitti, ad esempio la condivisione di una singola classe Customer tra due diverse viste, in cui ogni visualizzazione vuole essere salvata in posizioni diverse.

Il controller esegue la persistenza

In questo pattern, il controller contiene un riferimento sia al modello sia a un datastore ed è responsabile del mantenimento del modello. Il controller risponde agli eventi del ciclo di vita come Carica, Salva, Elimina e invia comandi al datastore per recuperare o aggiornare il modello.

Vantaggi:

  • Più facile da testare, il controller può superare un datastore fittizio su cui scrivere test.
  • Lo stesso modello può essere riutilizzato con più datastore semplicemente creando controller con datastore diversi.

Contro:

  • Il codice può essere più complesso da gestire.

AppController esegue la persistenza

In alcuni casi, c'è un controller di supervisione responsabile del passaggio da un MVC all'altro. L'AppController decide, ad esempio, che un pulsante "Indietro" trasferisca il client da una schermata di modifica (che contiene widget/formati MVC) a una schermata delle impostazioni.

Nel pattern AppController, AppController risponde agli eventi e modifica la schermata corrente dell'app inviando una chiamata al datastore per caricare i modelli necessari e creare tutte le viste e i controller corrispondenti per quella schermata.

Vantaggi:

  • Sposta il livello di persistenza ancora più in alto nello stack, dove può essere facilmente modificato.
  • Non inquina i controller di livello inferiore come DateChooseerController con l'esigenza di conoscere la persistenza.

Contro:

  • Ogni "pagina/schermata" dell'app ora richiede molto codice boilerplate per la scrittura o l'aggiornamento: modello, visualizzazione, controller, AppController.

La MVC è fondamentale per la progettazione delle app di Chrome. Consigliamo i seguenti framework MVC conformi a CSP per la scrittura di app di Chrome sicure e scalabili:

Risorse utili

Online

Libri