A maioria (todas?) Das estruturas que você está procurando resolve os mesmos problemas, mas elas fazem isso de maneiras ligeiramente diferentes, com objetivos ligeiramente diferentes.
Eu acho justo dizer que todos esses projetos resolveriam os problemas nessas categorias:
- Forneça um conjunto sensato de padrões
- Reduzir o código padrão
- Fornecer estrutura de aplicativo sobre os blocos de construção do BackboneJS
- Extrair padrões que os autores usam em seus aplicativos
Marionette, que construo desde dezembro de 2011, também tem alguns objetivos e ideais muito distintos:
- Arquitetura de aplicativos compostos
- Influência do padrão de mensagens corporativas
- Opções de modularização
- Uso incremental (nenhum requisito de tudo ou nada)
- Nenhum bloqueio do servidor
- Facilite a alteração desses padrões
- Código como configuração / sobre configuração
Não estou dizendo que nenhuma das outras estruturas tenha esses mesmos objetivos. Mas acho que a singularidade de Marionette vem da combinação desses objetivos.
Arquitetura de aplicativos compostos
Passei mais de 5 anos trabalhando em sistemas de software distribuído de clientes espessos usando WinForms e C #. Criei aplicativos para desktop, laptop (cliente inteligente), dispositivos móveis e aplicativos da web, todos compartilhando um conjunto funcional básico e trabalhando com o mesmo back-end do servidor várias vezes. Nesse período, aprendi o valor da modularização e mudei rapidamente um caminho de design de aplicativos compostos.
A idéia básica é "compor" a experiência de tempo de execução do seu aplicativo e processar a partir de várias partes menores e individuais que não necessariamente se conhecem. Eles se registram no sistema geral de aplicativos compostos e depois se comunicam através de vários meios de mensagens e chamadas dissociadas.
Eu escrevi um pouco sobre isso no meu blog, apresentando o Marionette como uma arquitetura de aplicativos composta para o Backbone:
Filas de mensagens / padrões
Os mesmos sistemas distribuídos em larga escala também aproveitaram o enfileiramento de mensagens, os padrões de integração corporativa (padrões de mensagens) e os barramentos de serviço para manipular as mensagens. Isso, mais do que qualquer outra coisa, teve uma tremenda influência na minha abordagem ao desenvolvimento de software desacoplado. Comecei a ver aplicativos WinForms em processo único, na memória, dessa perspectiva, e logo o desenvolvimento do meu servidor e aplicativos da web teve influência disso.
Isso se traduziu diretamente na forma como vejo o design do aplicativo Backbone. Eu forneço um agregador de eventos no Marionette, para o objeto Aplicativo de alto nível e para cada módulo que você cria no aplicativo.
Penso nas mensagens que posso enviar entre meus módulos: mensagens de comando, mensagens de eventos e muito mais. Também penso na comunicação do lado do servidor como mensagens com esses mesmos padrões. Alguns dos padrões já chegaram a Marionette, mas outros ainda não.
Modularização
A modularização do código é tremendamente importante. Criar pacotes pequenos e bem encapsulados que tenham um foco singular com pontos de entrada e saída bem definidos é obrigatório para qualquer sistema de qualquer tamanho e complexidade significativos.
Marionette fornece modularização diretamente através de suas module
definições. Mas também reconheço que algumas pessoas gostam do RequireJS e querem usá-lo. Portanto, forneço uma compilação padrão e uma compilação RequireJS compatível.
MyApp = new Backbone.Marionette.Application();
MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){
// your module code goes here
});
(Ainda não há nenhuma postagem de blog disponível para isso)
Uso Incremental
Essa é uma das filosofias principais em que faço parte de todas as partes da Marionette que posso: nenhum requisito de "tudo ou nada" para o uso da Marionette.
O backbone em si adota uma abordagem muito incremental e modular com todos os seus objetos de bloco de construção. Você é livre para escolher quais deseja usar e quando. Eu acredito firmemente nesse princípio e luto para garantir que Marionette funcione da mesma maneira.
Para esse fim, a maioria das peças que eu construí no Marionette é construída para ficar sozinha, trabalhar com as peças principais do Backbone e trabalhar ainda melhor.
Por exemplo, quase todos os aplicativos Backbone precisam mostrar dinamicamente uma exibição Backbone em um determinado local da tela. Os aplicativos também precisam lidar com o fechamento de visualizações antigas e a limpeza de memória quando uma nova é colocada no lugar. É aqui que a Marionette Region
entra para jogar. Uma região lida com o código padrão de fazer uma exibição, chamar render e inserir o resultado no DOM para você. Em seguida, feche essa visualização e a limpe para você, desde que ela tenha um método "fechado".
MyApp.addRegions({
someRegion: "#some-div"
});
MyApp.someRegion.show(new MyView());
Mas você não precisa usar as visualizações de Marionette para usar uma região. O único requisito é que você esteja estendendo do Backbone.View em algum momento da cadeia de protótipos do objeto. Se você optar por fornecer um close
método, um onShow
método ou outros, a Região de Marionette o chamará no momento certo.
Sem bloqueio do servidor
Crio aplicativos Backbone / Marionette sobre uma ampla variedade de tecnologias de servidor:
- ASP.NET MVC
- Ruby on Rails
- Ruby / Sinatra
- NodeJS / ExpressJS
- PHP / Slim
- Java
- Erlang
- ... e mais
JavaScript é JavaScript, quando se trata de rodar em um navegador. O JavaScript do lado do servidor também é incrível, mas tem efeito ou influência zero sobre como eu escrevo o JavaScript baseado no navegador.
Devido à diversidade de projetos que desenvolvi e tecnologias de back-end que meus clientes usam, não posso e não trancarei o Marionette em uma única pilha de tecnologia do lado do servidor por qualquer motivo. Não fornecerei um projeto padrão. Não fornecerei uma gema de rubi ou um pacote npm. Quero que as pessoas entendam que o Marionette não exige um servidor de back-end específico. É JavaScript baseado em navegador, e o back-end não importa.
Obviamente, apoio totalmente outras pessoas que fornecem pacotes para seu idioma e estrutura. Listo esses pacotes no Wiki e espero que as pessoas continuem a criar mais pacotes conforme acharem necessário. Mas isso é apoio da comunidade, não apoio direto da Marionette.
Alterar facilmente os padrões
Em meu esforço para reduzir o código padrão e fornecer padrões sensíveis (que é uma idéia que eu "emprestei" diretamente do LayoutManager de Tim Branyen), reconheço a necessidade de outros desenvolvedores usarem implementações ligeiramente diferentes das que eu.
Eu forneço renderização com base em <script>
tags embutidas para modelos, usando o modelo Underscore.js por padrão. Mas você pode substituir isso alterando os objetos Renderer
e / ou TempalteCache
no Marionette. Esses dois objetos fornecem o núcleo dos recursos de renderização, e há páginas wiki que mostram como mudar isso para mecanismos de modelagem específicos e diferentes maneiras de carregar modelos.
Com o v0.9 do Marionette, fica ainda mais fácil. Por exemplo, se você deseja substituir o uso de blocos de script de modelo embutido por modelos pré-compilados, é necessário substituir apenas um método no Renderer:
Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};
e agora o aplicativo inteiro usará modelos pré-compilados que você anexa ao template
atributo da sua visualização .
Eu até forneço um complemento Marionette.Async com v0.9 que permite que você ofereça modos de exibição de renderização assincronamente. Esforço-me continuamente para facilitar ao máximo a substituição dos comportamentos padrão no Marionette.
Código como configuração
Sou fã da "convenção sobre configuração" em certos contextos. É uma maneira poderosa de fazer as coisas, e Marionette fornece um pouco disso - embora não muito, honestamente. Muitas outras estruturas - especialmente o LayoutManager - oferecem mais convenções sobre configuração do que o Marionette.
Isso é feito com propósito e intenção.
Criei plug-ins, estruturas, complementos e aplicativos JavaScript suficientes para conhecer a dor de tentar fazer com que as convenções funcionem de maneira significativa e rápida. Isso pode ser feito com velocidade, mas geralmente ao custo de poder alterá-lo.
Para esse fim, adoto uma abordagem de "código como configuração" para o Marionette. Não forneço muitas APIs de "configuração" nas quais você pode fornecer um literal de objeto com valores estáticos que alteram uma variedade de comportamentos. Em vez disso, documento os métodos que cada objeto possui - tanto através do código fonte anotado quanto da documentação real da API - com a intenção de informar como alterar o Marionette para funcionar da maneira que você deseja.
Ao fornecer uma API limpa e clara para os objetos Marionette, crio uma situação em que a substituição do comportamento de um objeto específico ou do Marionette como um todo é relativamente simples e muito flexível. Eu sacrifico a API de configuração "simples" que exige flexibilidade de fornecer seu próprio código para que as coisas funcionem da maneira que você deseja.
Você não encontrará uma API "configure" ou "options" no Marionette. Mas você encontrará um grande número de métodos, cada um com uma finalidade muito específica, com assinaturas limpas, que facilitam a alteração de como o Marionette funciona.