La mayoría de (¿todos?) Los marcos que estás viendo resuelven los mismos problemas, pero lo hacen de maneras ligeramente diferentes con objetivos ligeramente diferentes.
Creo que es justo decir que todos estos proyectos resolverían los problemas en estas categorías:
- Proporcionar un conjunto razonable de valores predeterminados
- Reduce el código repetitivo
- Proporcione una estructura de aplicación sobre los bloques de construcción BackboneJS
- Extraer patrones que los autores usan en sus aplicaciones
Marionette, que he estado construyendo desde diciembre de 2011, también tiene en mente unos objetivos e ideales muy distintos:
- Arquitectura de aplicación compuesta
- Influencia del patrón de mensajería empresarial
- Opciones de modularización
- Uso incremental (sin requisito de todo o nada)
- Sin bloqueo de servidor
- Facilite cambiar esos valores predeterminados
- Código como configuración / sobre configuración
No digo que ninguno de los otros marcos tenga estos mismos objetivos. Pero creo que la singularidad de Marionette proviene de la combinación de estos objetivos.
Arquitectura de aplicaciones compuestas
Pasé más de 5 años trabajando en sistemas de software distribuido de cliente grueso utilizando WinForms y C #. Creé aplicaciones para computadoras de escritorio, computadoras portátiles (clientes inteligentes), dispositivos móviles y aplicaciones web, todas compartiendo un conjunto funcional central y trabajando muchas veces con el mismo servidor. En este tiempo, aprendí el valor de la modularización y rápidamente avancé por un camino de diseño de aplicaciones compuestas.
La idea básica es "componer" la experiencia de tiempo de ejecución de su aplicación y procesarla a partir de muchas piezas individuales más pequeñas que no necesariamente se conocen entre sí. Se registran en el sistema global de aplicaciones compuestas y luego se comunican a través de diversos medios de mensajes y llamadas desconectados.
Escribí un poco sobre esto en mi blog, presentando Marionette como una arquitectura de aplicación compuesta para Backbone:
Colas de mensajes / Patrones
Los mismos sistemas distribuidos a gran escala también aprovecharon las colas de mensajes, los patrones de integración empresarial (patrones de mensajes) y los buses de servicio para manejar los mensajes. Esto, más que cualquier otra cosa, tuvo una tremenda influencia en mi enfoque para el desarrollo de software desacoplado. Comencé a ver aplicaciones WinForms en memoria de un solo proceso desde esta perspectiva, y pronto mi desarrollo de aplicaciones web y del lado del servidor tomó influencia de esto.
Esto se ha traducido directamente en cómo veo el diseño de la aplicación Backbone. Proporciono un agregador de eventos en Marionette, tanto para el objeto Aplicación de alto nivel como para cada módulo que cree dentro de la aplicación.
Pienso en los mensajes que puedo enviar entre mis módulos: mensajes de comando, mensajes de eventos y más. También pienso en la comunicación del lado del servidor como mensajes con estos mismos patrones. Algunos de los patrones ya han llegado a Marionette, pero otros aún no.
Modularización
La modularización del código es tremendamente importante. Crear paquetes pequeños y bien encapsulados que tengan un enfoque singular con puntos de entrada y salida bien definidos es imprescindible para cualquier sistema de cualquier tamaño y complejidad significativos.
Marionette proporciona modularización directamente a través de sus module
definiciones. Pero también reconozco que a algunas personas les gusta RequireJS y quieren usar eso. Por lo tanto, proporciono una compilación estándar y una compilación compatible con RequireJS.
MyApp = new Backbone.Marionette.Application();
MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){
// your module code goes here
});
(No hay publicaciones de blog disponibles para esto, todavía)
Uso incremental
Esta es una de las filosofías centrales que cuento en cada parte de Marionette que puedo: no hay requisito de "todo o nada" para usar Marionette.
La red troncal en sí adopta un enfoque muy incremental y modular con todos sus objetos de bloques de construcción. Usted es libre de elegir cuáles quiere usar, cuándo. Creo firmemente en este principio y me esfuerzo por asegurarme de que Marionette funcione de la misma manera.
Con ese fin, la mayoría de las piezas que he incorporado a Marionette están hechas para estar solas, para trabajar con las piezas centrales de Backbone y para trabajar juntas aún mejor.
Por ejemplo, casi todas las aplicaciones Backbone necesitan mostrar dinámicamente una vista Backbone en un lugar particular de la pantalla. Las aplicaciones también deben manejar el cierre de vistas antiguas y la limpieza de memoria cuando se instala una nueva. Aquí es donde Region
entra Marionette's para jugar. Una región maneja el código repetitivo de tomar una vista, llamar a render y rellenar el resultado en el DOM por usted. Luego cerrará esa vista y la limpiará para usted, siempre que su vista tenga un método de "cierre".
MyApp.addRegions({
someRegion: "#some-div"
});
MyApp.someRegion.show(new MyView());
Pero no es necesario que use las vistas de Marionette para usar una región. El único requisito es que se extienda desde Backbone.View en algún punto de la cadena de prototipos del objeto. Si elige proporcionar un close
método, un onShow
método u otros, Marionette's Region lo llamará por usted en el momento adecuado.
Sin bloqueo de servidor
Construyo aplicaciones Backbone / Marionette sobre una amplia variedad de tecnologías de servidor:
- ASP.NET MVC
- Ruby on Rails
- Ruby / Sinatra
- NodeJS / ExpressJS
- PHP / Slim
- Java
- Erlang
- ... y más
JavaScript es JavaScript, cuando se trata de ejecutarse en un navegador. El JavaScript del lado del servidor también es increíble, pero tiene cero efecto o influencia en cómo escribo mi JavaScript basado en el navegador.
Debido a la diversidad en los proyectos que construí y las tecnologías de back-end que usan mis clientes, no puedo y no bloquearé a Marionette en una sola pila de tecnología del lado del servidor por ningún motivo. No proporcionaré un proyecto repetitivo. No proporcionaré una gema de rubí o un paquete npm. Quiero que la gente entienda que Marionette no requiere un servidor de fondo específico. Es JavaScript basado en navegador, y el back-end no importa.
Por supuesto, apoyo totalmente a otras personas que proporcionan paquetes para su idioma y marco. Enumero esos paquetes en el Wiki y espero que la gente continúe construyendo más paquetes a medida que vean una necesidad. Pero ese es el apoyo de la comunidad, no el apoyo directo de Marionette.
Cambie fácilmente los valores predeterminados
En mi esfuerzo por reducir el código repetitivo y proporcionar valores predeterminados razonables (que es una idea que directamente "tomé prestada" del LayoutManager de Tim Branyen), reconozco la necesidad de que otros desarrolladores utilicen implementaciones ligeramente diferentes a las mías.
Proporciono renderizado basado en <script>
etiquetas en línea para plantillas, usando la plantilla Underscore.js por defecto. Pero puede reemplazar esto cambiando los objetos Renderer
y / u TempalteCache
objetos en Marionette. Estos dos objetos proporcionan el núcleo de las capacidades de representación, y hay páginas wiki que muestran cómo cambiar esto para motores de plantillas específicos y diferentes formas de cargar plantillas.
Con v0.9 de Marionette, se vuelve aún más fácil. Por ejemplo, si desea reemplazar el uso de bloques de script de plantilla en línea con plantillas precompiladas, solo tiene que reemplazar un método en el Renderer:
Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};
y ahora toda la aplicación usará plantillas precompiladas que adjuntará al template
atributo de su vista .
Incluso proporciono un complemento Marionette.Async con v0.9 que le permite admitir vistas de representación asíncrona. Me esfuerzo continuamente para que sea lo más fácil posible reemplazar los comportamientos predeterminados en Marionette.
Código como configuración
Soy fanático de la "convención sobre la configuración" en ciertos contextos. Es una forma poderosa de hacer las cosas, y Marionette ofrece un poco de esto, aunque no demasiado, honestamente. Muchos otros marcos, especialmente LayoutManager, proporcionan más convenciones sobre la configuración que Marionette.
Esto se hace con propósito e intención.
He creado suficientes complementos, marcos, complementos y aplicaciones de JavaScript para conocer el dolor de tratar de hacer que las convenciones funcionen de manera significativa y rápida. Se puede hacer con velocidad, pero generalmente a costa de poder cambiarlo.
Con ese fin, adopto un enfoque de "código como configuración" para Marionette. No proporciono muchas API de "configuración" en las que puede proporcionar un objeto literal con valores estáticos que cambien una franja de comportamientos. En cambio, documente los métodos que tiene cada objeto, tanto a través del código fuente anotado como a través de la documentación API real, con la intención de decirle cómo cambiar Marionette para que funcione de la manera que desee.
Al proporcionar una API limpia y clara para los objetos Marionette, creo una situación en la que reemplazar el comportamiento de un objeto específico o Marionette en su conjunto es relativamente simple y muy flexible. Sacrifico las configuraciones de API "simples" para la flexibilidad de proporcionar su propio código para que las cosas funcionen de la manera que desee.
No encontrará una API de "configuración" u "opciones" en Marionette. Pero encontrará una gran cantidad de métodos que tienen un propósito muy específico, con firmas limpias, que facilitan cambiar la forma en que funciona Marionette.