Die meisten (alle?) Frameworks, die Sie betrachten, lösen dieselben Probleme, aber sie tun dies auf leicht unterschiedliche Weise mit leicht unterschiedlichen Zielen.
Ich denke, es ist fair zu sagen, dass all diese Projekte die Probleme in diesen Kategorien lösen würden:
- Stellen Sie sinnvolle Standardeinstellungen bereit
- Kesselschildcode reduzieren
- Stellen Sie die Anwendungsstruktur über den BackboneJS-Bausteinen bereit
- Extrahieren Sie Muster, die Autoren in ihren Apps verwenden
Marionette, die ich seit Dezember 2011 baue, hat auch einige sehr unterschiedliche Ziele und Ideale im Auge:
- Zusammengesetzte Anwendungsarchitektur
- Einfluss des Enterprise-Messaging-Musters
- Modularisierungsoptionen
- Inkrementelle Verwendung (keine Alles-oder-Nichts-Anforderung)
- Keine Server-Sperrung
- Machen Sie es sich einfach, diese Standardeinstellungen zu ändern
- Code als Konfiguration / Überkonfiguration
Ich sage nicht, dass keines der anderen Frameworks dieselben Ziele verfolgt. Aber ich denke, Marionettes Einzigartigkeit beruht auf der Kombination dieser Ziele.
Zusammengesetzte Anwendungsarchitektur
Ich habe mehr als 5 Jahre in verteilten Thick-Client-Softwaresystemen mit WinForms und C # gearbeitet. Ich habe Apps für Desktop, Laptop (Smart-Client), mobile Geräte und Webanwendungen erstellt, die alle einen Kernfunktionssatz gemeinsam nutzen und viele Male mit demselben Server-Back-End arbeiten. In dieser Zeit lernte ich den Wert der Modularisierung und ging sehr schnell einen Weg des Entwurfs zusammengesetzter Anwendungen.
Die Grundidee besteht darin, die Laufzeiterfahrung und den Prozess Ihrer Anwendung aus vielen kleineren, einzelnen Teilen zu "komponieren", die nicht unbedingt voneinander wissen. Sie registrieren sich beim gesamten zusammengesetzten Anwendungssystem und kommunizieren dann über verschiedene Mittel entkoppelter Nachrichten und Anrufe.
Ich habe in meinem Blog ein wenig darüber geschrieben und Marionette als zusammengesetzte Anwendungsarchitektur für Backbone vorgestellt:
Nachrichtenwarteschlangen / -muster
Dieselben verteilten Großsysteme nutzten auch Nachrichtenwarteschlangen, Unternehmensintegrationsmuster (Messaging-Muster) und Servicebusse, um die Nachrichten zu verarbeiten. Dies hatte vor allem einen enormen Einfluss auf meinen Ansatz zur entkoppelten Softwareentwicklung. Aus dieser Perspektive sah ich WinForms-Anwendungen mit einem einzigen Prozess im Speicher, und bald wurde meine serverseitige und Webanwendungsentwicklung davon beeinflusst.
Dies hat sich direkt darin niedergeschlagen, wie ich das Design von Backbone-Anwendungen betrachte. Ich stelle in Marionette einen Ereignisaggregator bereit, sowohl für das übergeordnete Anwendungsobjekt als auch für jedes Modul, das Sie in der Anwendung erstellen.
Ich denke an Nachrichten, die ich zwischen meinen Modulen senden kann: Befehlsnachrichten, Ereignismeldungen und mehr. Ich denke auch an die serverseitige Kommunikation als Nachrichten mit denselben Mustern. Einige der Muster haben bereits Eingang zu Marionette gefunden, andere noch nicht.
Modularisierung
Die Modularisierung von Code ist enorm wichtig. Das Erstellen kleiner, gut gekapselter Pakete mit einem einzigartigen Fokus und genau definierten Ein- und Ausstiegspunkten ist ein Muss für jedes System von erheblicher Größe und Komplexität.
Marionette bietet Modularisierung direkt durch seine module
Definitionen. Aber ich erkenne auch, dass einige Leute RequireJS mögen und das nutzen wollen. Daher biete ich sowohl einen Standard-Build als auch einen RequireJS-kompatiblen Build an.
MyApp = new Backbone.Marionette.Application();
MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){
// your module code goes here
});
(Dafür ist noch kein Blog-Beitrag verfügbar)
Inkrementelle Verwendung
Dies ist eine der Kernphilosophien, die ich in jeden Teil von Marionette einbringe, den ich kann: keine "Alles-oder-Nichts" -Anforderung für die Verwendung von Marionette.
Das Backbone selbst verfolgt mit all seinen Bausteinobjekten einen sehr inkrementellen und modularen Ansatz. Sie können frei wählen, welche Sie wann verwenden möchten. Ich glaube fest an dieses Prinzip und bemühe mich sicherzustellen, dass Marionette genauso funktioniert.
Zu diesem Zweck sind die meisten Teile, die ich in Marionette eingebaut habe, dafür gebaut, allein zu stehen, mit den Kernstücken von Backbone zu arbeiten und noch besser zusammenzuarbeiten.
Beispielsweise muss fast jede Backbone-Anwendung eine Backbone-Ansicht an einer bestimmten Stelle auf dem Bildschirm dynamisch anzeigen. Die Apps müssen auch alte Ansichten schließen und den Speicher bereinigen, wenn eine neue eingerichtet wird. Hier kommt Marionette Region
ins Spiel. Eine Region verarbeitet den Boilerplate-Code, mit dem Sie eine Ansicht erstellen, Rendering aufrufen und das Ergebnis für Sie in das DOM einfügen. Dann wird diese Ansicht geschlossen und für Sie bereinigt, vorausgesetzt, Ihre Ansicht verfügt über eine "Schließen" -Methode.
MyApp.addRegions({
someRegion: "#some-div"
});
MyApp.someRegion.show(new MyView());
Sie müssen jedoch nicht die Ansichten von Marionette verwenden, um eine Region zu verwenden. Die einzige Voraussetzung ist, dass Sie sich irgendwann in der Prototypenkette des Objekts von Backbone.View aus erweitern. Wenn Sie eine close
Methode, eine onShow
Methode oder andere bereitstellen , wird Marionette's Region sie zum richtigen Zeitpunkt für Sie aufrufen.
Keine Server-Sperre
Ich erstelle Backbone / Marionette-Apps auf einer Vielzahl von Servertechnologien:
- ASP.NET MVC
- Ruby on Rails
- Rubin / Sinatra
- NodeJS / ExpressJS
- PHP / Slim
- Java
- Erlang
- ... und mehr
JavaScript ist JavaScript, wenn es darum geht, in einem Browser ausgeführt zu werden. Serverseitiges JavaScript ist ebenfalls fantastisch, hat jedoch keinen Einfluss darauf, wie ich mein browserbasiertes JavaScript schreibe.
Aufgrund der Vielfalt der von mir erstellten Projekte und der von meinen Kunden verwendeten Back-End-Technologien kann und wird ich Marionette aus irgendeinem Grund nicht an einen einzelnen serverseitigen Technologie-Stack binden. Ich werde kein Boilerplate-Projekt bereitstellen. Ich werde kein Rubinjuwel oder ein npm-Paket zur Verfügung stellen. Ich möchte, dass die Leute verstehen, dass Marionette keinen bestimmten Back-End-Server benötigt. Es ist browserbasiertes JavaScript, und das Back-End spielt keine Rolle.
Natürlich unterstütze ich andere Menschen, die Pakete für ihre Sprache und ihren Rahmen anbieten. Ich liste diese Pakete im Wiki auf und hoffe, dass die Leute weiterhin mehr Pakete erstellen, wenn sie einen Bedarf sehen. Aber das ist Community-Unterstützung, keine direkte Unterstützung von Marionette.
Ändern Sie einfach die Standardeinstellungen
In meinem Bestreben, den Code für das Boilerplate zu reduzieren und sinnvolle Standardeinstellungen bereitzustellen (eine Idee, die ich direkt vom LayoutManager von Tim Branyen "ausgeliehen" habe), erkenne ich die Notwendigkeit, dass andere Entwickler etwas andere Implementierungen verwenden als ich.
Ich biete Rendering basierend auf Inline- <script>
Tags für Vorlagen an, wobei standardmäßig Underscore.js Vorlagen verwendet werden. Sie können dies jedoch ersetzen, indem Sie die Renderer
und / oder TempalteCache
Objekte in Marionette ändern . Diese beiden Objekte bilden den Kern der Rendering-Funktionen, und es gibt Wiki-Seiten, die zeigen, wie Sie dies für bestimmte Template-Engines und verschiedene Arten des Ladens von Vorlagen ändern können.
Mit v0.9 von Marionette wird es noch einfacher. Wenn Sie beispielsweise die Verwendung von Inline-Vorlagenskriptblöcken durch vorkompilierte Vorlagen ersetzen möchten, müssen Sie im Renderer nur eine Methode ersetzen:
Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};
Jetzt verwendet die gesamte Anwendung vorkompilierte Vorlagen, die Sie an das template
Attribut Ihrer Ansicht anhängen .
Ich biete sogar ein Marionette.Async-Add-On mit Version 0.9 an, mit dem Sie das asynchrone Rendern von Ansichten unterstützen können. Ich bin ständig bemüht, es so einfach wie möglich zu machen, das Standardverhalten in Marionette zu ersetzen.
Code als Konfiguration
Ich bin ein Fan von "Konvention über Konfiguration" in bestimmten Kontexten. Es ist eine leistungsstarke Methode, um Dinge zu erledigen, und Marionette bietet ein wenig davon - wenn auch nicht zu viel, ehrlich. Viele andere Frameworks - insbesondere LayoutManager - bieten mehr Konventionen über die Konfiguration als Marionette.
Dies geschieht mit Absicht und Absicht.
Ich habe genug JavaScript-Plugins, Frameworks, Add-Ons und Anwendungen erstellt, um zu wissen, wie schwierig es ist, Konventionen auf sinnvolle und schnelle Weise zum Laufen zu bringen. Dies kann mit Geschwindigkeit erfolgen, jedoch normalerweise auf Kosten einer Änderung.
Zu diesem Zweck verfolge ich Marionette als "Code als Konfiguration". Ich biete nicht viele "Konfigurations" -APIs an, in denen Sie ein Objektliteral mit statischen Werten bereitstellen können, die eine Reihe von Verhaltensweisen ändern. Stattdessen dokumentiere ich die Methoden, über die jedes Objekt verfügt - sowohl durch kommentierten Quellcode als auch durch die eigentliche API-Dokumentation -, um Ihnen zu erklären, wie Sie Marionette so ändern können, dass sie wie gewünscht funktioniert.
Durch die Bereitstellung einer sauberen und klaren API für die Marionettenobjekte schaffe ich eine Situation, in der das Ersetzen des Verhaltens eines bestimmten Objekts oder der Marionette als Ganzes relativ einfach und sehr flexibel ist. Ich opfere die "einfachen" Konfigurations-API-Aufrufe für die Flexibilität, Ihren eigenen Code bereitzustellen, damit die Dinge so funktionieren, wie Sie es möchten.
In Marionette finden Sie keine API "Konfigurieren" oder "Optionen". Sie werden jedoch eine große Anzahl von Methoden finden, die jeweils einem bestimmten Zweck dienen, mit sauberen Signaturen, die es einfach machen, die Funktionsweise von Marionette zu ändern.