La maggior parte (tutti?) Dei framework che stai esaminando risolvono gli stessi problemi, ma lo fanno in modi leggermente diversi con obiettivi leggermente diversi.
Penso che sia giusto dire che tutti questi progetti risolverebbero i problemi in queste categorie:
- Fornire una serie ragionevole di valori predefiniti
- Ridurre il codice del boilerplate
- Fornire la struttura dell'applicazione sopra i blocchi predefiniti di BackboneJS
- Estrai i pattern che gli autori usano nelle loro app
Marionette, che costruisco dal dicembre 2011, ha in mente anche alcuni obiettivi e ideali molto distinti:
- Architettura dell'applicazione composita
- Influenza del modello di messaggistica aziendale
- Opzioni di modularizzazione
- Uso incrementale (nessun requisito tutto o niente)
- Nessun blocco del server
- Semplifica la modifica di tali valori predefiniti
- Codice come configurazione / sopra configurazione
Non sto dicendo che nessuno degli altri framework abbia gli stessi obiettivi. Ma penso che l'unicità di Marionette derivi dalla combinazione di questi obiettivi.
Architettura dell'applicazione composita
Ho trascorso più di 5 anni a lavorare in sistemi software distribuiti a client spesso usando WinForms e C #. Ho creato app per desktop, laptop (smart-client), dispositivi mobili e applicazioni Web, condividendo tutte un set funzionale di base e lavorando più volte con lo stesso back-end del server. In questo periodo ho appreso il valore della modularizzazione e ho intrapreso molto rapidamente un percorso di progettazione di applicazioni composite.
L'idea di base è quella di "comporre" l'esperienza di runtime dell'applicazione e di elaborare molti singoli pezzi più piccoli che non si conoscono necessariamente. Si registrano con il sistema complessivo di applicazione composita e quindi comunicano attraverso vari mezzi di messaggi e chiamate disaccoppiati.
Ho scritto un po 'di questo sul mio blog, introducendo Marionette come architettura composita per l'applicazione Backbone:
Code / pattern dei messaggi
Gli stessi sistemi distribuiti su larga scala hanno inoltre sfruttato l'accodamento dei messaggi, i modelli di integrazione aziendale (modelli di messaggistica) e i bus di servizio per gestire i messaggi. Questo, più di ogni altra cosa, ha avuto un'enorme influenza sul mio approccio allo sviluppo del software disaccoppiato. Ho iniziato a vedere le applicazioni WinForms single-process in memoria da questa prospettiva, e presto il mio lato server e lo sviluppo di applicazioni web ne hanno influenzato.
Questo si è tradotto direttamente nel modo in cui guardo il design dell'applicazione Backbone. Fornisco un aggregatore di eventi in Marionette, sia per l'oggetto Application di alto livello, sia per ciascun modulo creato all'interno dell'applicazione.
Penso ai messaggi che posso inviare tra i miei moduli: messaggi di comando, messaggi di eventi e altro ancora. Penso anche alla comunicazione lato server come messaggi con questi stessi schemi. Alcuni dei motivi si sono già fatti strada verso Marionette, ma alcuni non l'hanno ancora fatto.
La modularizzazione
La modularizzazione del codice è estremamente importante. La creazione di pacchetti piccoli e ben incapsulati con un focus singolare con punti di entrata e uscita ben definiti è un must per qualsiasi sistema di dimensioni e complessità significative.
Marionette fornisce la modularizzazione direttamente attraverso le sue module
definizioni. Ma riconosco anche che alcune persone come RequireJS e vogliono usarlo. Quindi fornisco sia una build standard che una build compatibile con RequireJS.
MyApp = new Backbone.Marionette.Application();
MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){
// your module code goes here
});
(Non ci sono ancora post sul blog disponibili per questo)
Uso incrementale
Questa è una delle filosofie fondamentali in cui mi concentro su ogni parte della marionetta che posso: nessun requisito "tutto o niente" per l'uso della marionetta.
Backbone stesso adotta un approccio molto incrementale e modulare con tutti i suoi oggetti di blocco. Sei libero di scegliere quali vuoi usare, quando. Credo fermamente in questo principio e mi sforzo di assicurarmi che la Marionetta funzioni allo stesso modo.
A tal fine, la maggior parte dei pezzi che ho incorporato in Marionette sono costruiti per essere isolati, per lavorare con i pezzi principali di Backbone e per lavorare insieme ancora meglio.
Ad esempio, quasi tutte le applicazioni Backbone devono mostrare dinamicamente una vista Backbone in un determinato punto dello schermo. Le app devono anche gestire la chiusura di vecchie viste e la pulizia della memoria quando ne viene creata una nuova. È qui che Region
entra in gioco Marionette . Un'area gestisce il codice del boilerplate per visualizzare una vista, chiamare il rendering su di essa e inserire il risultato nel DOM per te. Quindi chiuderà quella vista e la pulirà per te, a condizione che la tua vista abbia un metodo di "chiusura" su di essa.
MyApp.addRegions({
someRegion: "#some-div"
});
MyApp.someRegion.show(new MyView());
Ma non è necessario utilizzare le visualizzazioni di Marionette per utilizzare una regione. L'unico requisito è che si stia estendendo da Backbone.View ad un certo punto nella catena di prototipi dell'oggetto. Se scegli di fornire un close
metodo, un onShow
metodo o altri, la Regione delle Marionette lo chiamerà per te al momento giusto.
Nessun blocco del server
Realizzo app Backbone / Marionette su un'ampia gamma di tecnologie server:
- ASP.NET MVC
- Ruby on Rails
- Rubino / Sinatra
- NodeJS / ExpressJS
- PHP / Slim
- Giava
- Erlang
- ... e altro ancora
JavaScript è JavaScript, quando si tratta di funzionare in un browser. Anche il lato server JavaScript è fantastico, ma non ha alcun effetto o influenza su come scrivo JavaScript basato sul mio browser.
A causa della diversità dei progetti che ho realizzato e delle tecnologie di back-end utilizzate dai miei clienti, non posso e non voglio bloccare Marionette su un singolo stack tecnologico lato server per nessun motivo. Non fornirò un progetto di boilerplate. Non fornirò una gemma rubino o un pacchetto npm. Voglio che le persone capiscano che Marionette non richiede un server back-end specifico. È JavaScript basato su browser e il back-end non ha importanza.
Ovviamente, appoggio pienamente altre persone fornendo pacchetti per la loro lingua e struttura. Elenco questi pacchetti nel Wiki e spero che le persone continuino a creare più pacchetti quando ne vedono la necessità. Ma questo è il supporto della comunità, non il supporto diretto di Marionette.
Modifica facilmente i valori predefiniti
Nel mio tentativo di ridurre il codice del boilerplate e fornire impostazioni predefinite ragionevoli (che è un'idea che ho "preso in prestito" direttamente dal LayoutManager di Tim Branyen), riconosco la necessità che altri sviluppatori utilizzino implementazioni leggermente diverse rispetto a me.
Fornisco il rendering basato su <script>
tag incorporati per i modelli, usando il template Underscore.js per impostazione predefinita. Ma puoi sostituirlo cambiando gli oggetti Renderer
e / o TempalteCache
in Marionette. Questi due oggetti forniscono il nucleo delle funzionalità di rendering e ci sono pagine wiki che mostrano come modificarlo per motori di template specifici e modi diversi di caricare i template.
Con la v0.9 di Marionette, diventa ancora più facile. Ad esempio, se si desidera sostituire l'uso di blocchi di script modello inline con modelli precompilati, è necessario sostituire un solo metodo sul Renderer:
Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};
e ora l'intera applicazione utilizzerà modelli precompilati da allegare template
all'attributo della vista .
Fornisco anche un componente aggiuntivo Marionette.Async con v0.9 che consente di supportare il rendering asincrono delle viste. Mi sforzo continuamente di semplificare il più possibile la sostituzione dei comportamenti predefiniti in Marionette.
Codice come configurazione
Sono un fan della "convenzione sulla configurazione" in determinati contesti. È un modo potente per fare le cose, e Marionette ne fornisce un po ', anche se non troppo, onestamente. Molti altri framework, in particolare LayoutManager, forniscono più convenzioni sulla configurazione rispetto a Marionette.
Questo viene fatto con uno scopo e un intento.
Ho creato abbastanza plugin, framework, componenti aggiuntivi e applicazioni JavaScript per conoscere il dolore di provare a far funzionare le convenzioni in modo rapido e significativo. Può essere fatto con velocità, ma di solito a costo di poterlo cambiare.
A tal fine, prendo un approccio "code as configuration" a Marionette. Non fornisco molte API di "configurazione" in cui è possibile fornire un oggetto letterale con valori statici che cambiano una serie di comportamenti. Invece, documento i metodi che ogni oggetto ha - sia attraverso il codice sorgente annotato che attraverso la documentazione API effettiva - con l'intento di dirti come cambiare la marionetta in modo che funzioni nel modo desiderato.
Fornendo un'API pulita e chiara per gli oggetti Marionette, creo una situazione in cui sostituire il comportamento di un oggetto specifico o Marionette nel suo insieme è relativamente semplice e molto flessibile. Sacrifico le "semplici" API di configurazione per la flessibilità di fornire il proprio codice per far funzionare le cose nel modo desiderato.
Non troverai un'API "configura" o "opzioni" in Marionette. Ma troverai un gran numero di metodi che hanno ciascuno uno scopo molto specifico, con firme pulite, che rendono facile cambiare il modo in cui funziona la marionetta.