您正在查看的大多数(全部?)框架都解决了相同的问题,但它们的实现方式略有不同,目标略有不同。
我认为可以公平地说,所有这些项目都可以解决这些类别的问题:
提供合理的默认设置
减少样板代码
在 BackboneJS 构建块之上提供应用程序结构
提取作者在其应用程序中使用的模式
我自 2011 年 12 月以来一直在构建的 Marionette 也有一些非常不同的目标和理想:
复合应用架构
企业消息模式影响
模块化选项
增量使用(无全有或全无要求)
无服务器锁定
轻松更改这些默认值
代码作为配置/过度配置
我并不是说其他框架都没有这些相同的目标。但我认为 Marionette 的独特性来自于这些目标的结合。
复合应用架构
我在使用 WinForms 和 C# 的胖客户端分布式软件系统中工作了 5 年多。我为台式机、笔记本电脑(智能客户端)、移动设备和 Web 应用程序构建了应用程序,所有应用程序都共享一个核心功能集并多次使用相同的服务器后端。这段时间,我了解了模块化的值(value),并很快走上了复合应用程序设计的道路。
基本思想是“组合”您的应用程序的运行时体验,并由许多彼此不一定了解的较小的独立部分进行处理。它们将自己注册到整个复合应用系统,然后通过各种解耦消息和调用的方式进行通信。
我在我的博客上写了一些关于这个的内容,介绍了 Marionette 作为 Backbone 的复合应用程序架构:
http://lostechies.com/derickbailey/2011/11/17/introduction-to-composite-javascript-apps/
http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
消息队列/模式
同样大规模的分布式系统也利用消息队列、企业集成模式(消息模式)和服务总线来处理消息。最重要的是,这对我的解耦软件开发方法产生了巨大影响。我开始从这个角度看到单进程、内存中的 WinForms 应用程序,很快我的服务器端和 Web 应用程序开发就受到了影响。
这直接转化为我如何看待 Backbone 应用程序设计。我在 Marionette 中为高级 Application 对象和您在应用程序中创建的每个模块提供了一个事件聚合器。
我考虑可以在我的模块之间发送的消息:命令消息、事件消息等等。我还将服务器端通信视为具有这些相同模式的消息。有些模式已经进入了 Marionette,但有些还没有。
http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/
http://lostechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lessons-learned/
http://lostechies.com/derickbailey/2009/12/23/understanding-the-application-controller-through-object-messaging-patterns/ (WinForms 代码,但仍然适用)
模块化
代码的模块化非常重要。对于任何具有显着规模和复杂性的系统来说,创建具有单一焦点和明确定义的入口和导出点的小型、封装良好的包是必须的。
Marionette 直接通过它的
module
提供模块化定义。但我也认识到有些人喜欢 RequireJS 并想使用它。所以我提供了一个标准的构建和一个 RequireJS 兼容的构建。
MyApp = new Backbone.Marionette.Application();
MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){
// your module code goes here
});
(目前还没有可用的博客文章)
增量使用
这是我在 Marionette 的每个部分都尽我所能的核心理念之一:使用 Marionette 没有“全有或全无”的要求。
Backbone 本身采用非常增量和模块化的方法来处理它的所有构建块对象。您可以自由选择要使用的时间和时间。我坚信这一原则,并努力确保 Marionette 以同样的方式工作。
为此,我在 Marionette 中构建的大部分部件都是独立的,可以与 Backbone 的核心部件一起工作,并且可以更好地协同工作。
例如,几乎每个 Backbone 应用程序都需要在屏幕的特定位置动态显示 Backbone View 。应用程序还需要处理关闭旧 View 并在放置新 View 时清理内存。这是牵线木偶的地方
Region
进来玩。区域处理样板代码,即获取 View 、调用其上的渲染并将结果填充到 DOM 中。然后将关闭该 View 并为您清理它,前提是您的 View 具有“关闭”方法。
MyApp.addRegions({
someRegion: "#some-div"
});
MyApp.someRegion.show(new MyView());
但是您不需要使用 Marionette 的 View 来使用区域。唯一的要求是您在对象原型(prototype)链中的某个点从 Backbone.View 扩展。如果您选择提供
close
方法,一个
onShow
方法,或者其他,木偶之域会在合适的时候为你调用。
http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/
无服务器锁定
我在各种服务器技术之上构建 Backbone/Marionette 应用程序:
ASP.NET MVC
Ruby on Rails
ruby /辛纳屈
NodeJS/ExpressJS
PHP/ slim
Java
Erlang
...以及更多
JavaScript 就是在浏览器中运行的 JavaScript。服务器端 JavaScript 也很棒,但它对我如何编写基于浏览器的 JavaScript 的影响或影响为零。
由于我构建的项目和客户使用的后端技术的多样性,我不能也不会出于任何原因将 Marionette 锁定在单个服务器端技术堆栈中。我不会提供样板项目。我不会提供 ruby gem 或 npm 包。我希望人们了解 Marionette 不需要特定的后端服务器。它是基于浏览器的 JavaScript,后端无关紧要。
当然,我完全支持其他人为他们的语言和框架提供包。我在 Wiki 中列出了这些包,并希望人们在看到需要时继续构建更多的包。但那是社区支持,而不是来自 Marionette 的直接支持。
https://github.com/derickbailey/backbone.marionette/wiki/Available-packages
轻松更改默认值
为了减少样板代码并提供合理的默认值(这是我直接从 Tim Branyen 的 LayoutManager 中“借用”的想法),我认识到其他开发人员需要使用与我略有不同的实现。
我提供基于内联的渲染
<script>
模板标签,默认使用 Underscore.js 模板。但是您可以通过更改
Renderer
来替换它和/或
TempalteCache
牵线木偶中的对象。这两个对象提供了渲染功能的核心,并且有一些 wiki 页面展示了如何针对特定的模板引擎和加载模板的不同方式进行更改。
使用 Marionette v0.9,它变得更加容易。例如,如果要将内联模板脚本块的使用替换为预编译模板,则只需替换 Renderer 上的一种方法:
Backbone.Marionette.Renderer.render = function(template, data){
return template(data);
};
现在整个应用程序将使用您附加到 View
template
的预编译模板。属性。
我什至提供了带有 v0.9 的 Marionette.Async 附加组件,它允许您支持异步渲染 View 。我不断努力使替换 Marionette 中的默认行为尽可能容易。
代码即配置
在某些情况下,我是“约定优于配置”的粉丝。这是完成工作的一种强大方式,而 Marionette 提供了一点点 - 虽然不是太多,但老实说。许多其他框架 - 特别是 LayoutManager - 比 Marionette 提供更多的配置约定。
这是有目的和意图的。
我已经构建了足够多的 JavaScript 插件、框架、附加组件和应用程序,以了解尝试让约定以有意义且快速的方式工作的痛苦。它可以快速完成,但通常以能够改变它为代价。
为此,我对 Marionette 采取了“代码即配置”的方法。我没有提供很多“配置”API,您可以在其中提供带有静态值的对象文字,这些静态值会改变一系列行为。相反,我记录了每个对象具有的方法——通过带注释的源代码和实际的 API 文档——目的是告诉你如何改变 Marionette 以按照你想要的方式工作。
通过为 Marionette 对象提供干净清晰的 API,我创造了一种情况,即替换特定对象或 Marionette 整体的行为相对简单且非常灵活。我牺牲了“简单”配置 API 调用的灵活性,以提供您自己的代码以使事情以您想要的方式工作。
您不会在 Marionette 中找到“配置”或“选项”API。但是您会发现大量方法,每个方法都用于非常特定的目的,具有清晰的签名,可以轻松更改 Marionette 的工作方式。
我是一名优秀的程序员,十分优秀!