标题：Robotlegs
Robotlegs
Robotlegs 是一个用来开发Flash, Flex, 和 AIR应用的纯 AS3 微架构(框架).  Robotlegs LOGORobotlegs 专注于将应用程序各层排布在一起并提供它们相互通讯的机制. Robotlegs 试图通过提供一种解决常见开发问题的经过时间检验的架构解决方案来加速开发. Robotlegs 无意锁定你到框架, 你的类就是你的类的样子, 而且应该很容易地切换到其他框架.
框架提供一个基于 Model-View-Controller元设计模式的默认实现. 这个实现提供一个针对应用程序结构和设计的强烈建议. 虽然它确实轻微减低了你的应用程序的便携性, 不过它依然以最低限度影响你的具体类为目标. 通过扩展 MVCS实现类, 你可以获得很多有用的方法和属性.
你不必使用Robotlegs的标准 MVCS实现.你可以使用它的任意部分, 或者完全不使用它, 或者使用自己的实现来适应你的需求. 它是为了提供合适的参考实现和快速开始使用 Robotlegs 而被包含进来。
依赖注入
Robotlegs 围绕 依赖注入设计模式展开.    
最简单地, 依赖注入是为对象提供实例变量或属性的行为. 当你传递一个变量到一个类的构造函数, 你在使用依赖注入. 当你设置一个类的属性, 你在使用依赖注入. 如果你不是使用严格的过程或线性方式编写AS3, 很可能你现在就在使用依赖注入。
Robotlegs 使用基于元数据的自动依赖注入. 这是为了方便开发而提供, 而且在排布应用程序并提供类和它所需要的依赖时，可以减少很多代码量. 虽然完全可以手动提供这些依赖, 但是允许框架来履行这些职责可以减少出错的机会，并且通常可以加快编码进程。.
使用 InjectorsRobotlegs 采用一种适配器(adapter)机制来为框架提供依赖注入机制. 默认地, 框架配备了 SwiftSuspenders注入/反射库来适合这个要求. 另有 SmartyPants-IoC 和 Spring Actionscript 的适配器可以使用. 可能有潜在的特定需求来使用其它的依赖注入适配器, 但是如果没有特别的理由, 建议使用默认的 SwiftSuspenders, 因为它为 Robotlegs 做了一些特别调整.
SwiftSuspenders 适配器注入语法SwiftSuspenders 支持三种类型的依赖注入：属性(域)注入、参数(方法/设值)和 注入构造注入。
这里我们将特别介绍属性注入, 以及在 Robotlegs 里如何使用. 将属性注入类有两种选择. 你可以使用未命名，或命名的注入:
[Inject]
public var myDependency:Depedency; //未命名注入[Inject(name="myNamedDependency")]
public var myNamedDependency:NamedDepedency; //命名注入 
Robotlegs 里三处提供了注入映射. MediatorMap, CommandMap, 和直接通过 Injector . MediatorMap 和 CommandMap 也都是使用 Injector, 但它们同时做了一些各自层(tier)所需要的额外工作. 顾名思义, MediatorMap 用来映射 Mediator, CommandMap 用来映射 Command, 其它所有需要被注入的内容 (包括但不限于 Model) 都要直接使用 Injector 映射.Injector 类的映射注入具体 Injector 类的适配器都遵照 IInjector 接口. 这个接口为不同的依赖注入解决方案提供了统一的API. 本文档专注于 SwiftSuspenders, 但这些语法同样适应于其它任何遵照 Iinjector 接口的 Injector.
injector是你应用程序里所发生的所有依赖注入的生产车间. 它用来注入框架 actor, 同时也可以用来执行你的应用程序所需要的任何其它注入. 这包括但不限于 RemoteObjects, HTTPServices, 工厂类, 或者事实上任何有可能成为你的对象所需要的依赖的类/接口.
下面是实现 IInjector 接口的类所提供的四个映射方法:
mapValue 
mapValue 用来映射一个对象的特定实例到一个 injector. 当请求一个特定的类，使用类的这个特定实例来注入.
//你的应用程序中某个映射/配置发生的地方
var myClassInstance:MyClass = new MyClass();
injector.mapValue(MyClass, myClassInstance);//在接收注入的类中
[Inject]
public var myClassInstance:MyClassmapValue(whenAskedFor:Class, instantiateClass:Class, named:String = null) 
MyClass 的实例被创建和保留，并在被请求的时候被注入. 当此类被请求的时候，这个实例被用来满足这个注入请求. 请注意很重要的一点，因为你已经手动创建并通过 mapValue 映射了一个类实例, 这个实例所需要的依赖将不会被自动注入. 你需要手动或通过 injector 注入这些依赖:
injector.injectInto(myClassInstance); 
这将立即为此实例提供已映射的可以注入的属性。.
mapClass 
mapClass 为每一个注入请求提供这个被映射的类的一个 特有( unique) 实例.
//你的应用程序中某个映射/配置发生的地方
injector.mapClass(MyClass);//在第一个接收注入的类里
[Inject]
public var myClassInstance:MyClass//在第二个接收注入的类里
[Inject]
public var myClassInstance:MyClass 
为上面的每一个注入提供MyClass的 特有( unique) 实例来完成请求.
mapClass(whenAskedFor:Class, named:String = null) 
injector 提供了一个方法来实例化被映射的对象:
injector.mapClass(MyClass);
var myClassInstance:MyClass = injector.instantiate(MyClass); 
这提供你的对象的一个实例，并填充了此对象包含的所有被映射的注入点(injection points).
mapSingleton 
mapSingleton 为每一个注入请求提供类的一个 单一_(_single) 实例. 为所有映射提供类的单一实例确保你维护一个一致的状态并且不用担心创建被此类的多余实例. 这是一个被框架强制和管理的单一实例, 而不是一个在类内部强制的单例(Singleton).
//你的应用程序中某个映射/配置发生的地方
injector.mapSingleton(MyClass);//在第一个接收注入的类里
[Inject]
public var myClassInstance:MyClass//在第二个接收注入的类里
[Inject]
public var myClassInstance:MyClass 
在上面的例子里, 两个注入请求都将由被请求类的相同实例填充. 这个注入是被延迟的, 即对象直到第一次被请求才被实例化.
mapSingletonOf(whenAskedFor:Class, useSingletonOf:Class, named:String = null)mapSingletonOf 
mapSingletonOf在功能上非常像 mapSingleton. 它对映射抽象类和接口很有用, 而 mapSingleton 用来映射具体类实现.
//你的应用程序中某个映射/配置发生的地方
injector.mapSingletonOf(IMyClass, MyClass); //MyClass implements IMyClass//在第一个接收注入的类里
[Inject]
public var myClassInstance:IMyClass//在第二个接收注入的类里
[Inject]
public var myClassInstance:IMyClass 
这个注入方法对创建使用多态的更具可测性的类非常有用. 在下面的 Service 实例章节可以找到一个例子.MediatorMap 类的依赖注入MediatorMap 实现 IMediatorMap 接口. IMediatorMap 提供两个方法来将你的 mediators 映射到 view 并注册它们以便用来注入.
mapView(viewClassOrName:*, mediatorClass:Class, injectViewAs:Class = null, autoCreate:Boolean = true, autoRemove:Boolean = true):void 
mapView接受一个视图类, MyAwesomeWidget, 或者一个视图的类全名, com.me.app.view.components::MyAwesomeWidget作为第一个参数. 第二个参数是将要作为视图组件中介的 Mediator 类. [injectViewAs 内容未完成], 最后的两个参数 autoCreate 和 autoRemove 提供方便的自动管理 mediator 的布尔值开关.
//在你的程序里某个映射/配置发生的地方
mediatorMap.mapView(MyAwesomeWidget, MyAwesomeWidgetMediator);//在conntextView 的显示列表里的某个地方
var myAwesomeWidget:MyAwesomeWidget = new MyAwesomeWidget();
this.addChild(myAwesomeWidget); // ADDED_TO_STAGE 事件被抛出, 触发这个视图组件的中介机制 
这个方法使用了自动中介机制. 手动中介，以及对此方面更深入的内容将稍后在 Mediators章节中介绍.
CommandMap 类的依赖注入CommandMap 类实现 ICommandMap 接口, 提供一个用来将 command 映射到到触发它们的框架事件的方法.
mapEvent(eventType:String, commandClass:Class, eventClass:Class = null, oneshot:Boolean = false) 
你要提供给 commandMap 一个可以执行的类, 执行它的事件类型, 可选的这个事件的强类型, 以及这个 command 是否只被执行一次并且随即取消映射的布尔值开关.
这个可选的强类型事件类用来对Flash平台的"magic string"事件类型系统做额外的保护.以避免采用相同事件类型字符串的不同事件类之间的冲突.
//在你的程序里某个映射/配置发生的地方
commandMap.mapEvent(MyAppDataEvent.DATA_WAS_RECEIVED, MyCoolCommand, MyAppDataEvent);//在事件被广播的另外一个框架actor里
//这触发了随后被执行的被映射的 command
dispatch(new MyAppDataEvent(MyAppDataEvent.DATA_WAS_RECEIVED, someTypedPayload))
The Context
Context 是所有 Robotlegs 具体实现的中心. 一个 Context, 或者也许多个 Context, 提供其它层进行通讯的机制. 一个应用程序并非只能使用一个 Context, 但大多情况下一个 Context 就足够了. 如果在 Flash 平台上创建模块化应用程序, 多个 Context 就是必须的了. Context 在一个应用程序里有三个功能: 提供初始化, [de-initialization – 非初始化?], 和用来通讯的事件中心bus.
package org.robotlegs.examples.bootstrap
{
import flash.display.DisplayObjectContainer;
import org.robotlegs.base.ContextEvent;
import org.robotlegs.core.IContext;
import org.robotlegs.mvcs.Context;
public class ExampleContext extends Context implements IContext
{
public function UnionChatContext(contextView:DisplayObjectContainer)
{
super(contextView);
}
override public function startup():void
{
//这个 Context 只映射一个 command 到 ContextEvent.STARTUP 事件. 
//这个 StartupCommand 将映射其它将在应用程序里使用的的 command, 
//mediator, service, 和 model.
commandMap.mapEvent( ContextEvent.STARTUP, StartupCommand, ContextEvent, true );
//启动应用程序 (触发 StartupCommand)
dispatch(new ContextEvent(ContextEvent.STARTUP));
}
}
}
MVCS参考实现
Robotlegs 装备了一个参考实现. 这个实现遵照经典的 Model-View-Controller (MVC) 元设计模式, 另外增加了第四个叫做 Service 的 actor. 这些层在本文档中通称为"核心 actor", 或者简称为"actor".
MVCS提供一个应用程序的框架概况. 通过将几个经过时间检验的设计模式整合到一个具体实现, Robotlegs 的 MVCS实现可以用做创建你的应用程序的一致方案. 通过这些架构概念着手一个应用程序, 你甚至可以在开始你的设计之前避免很多常见的障碍:分离 组织 解耦。 
分离  
MVCS提供一种将你的应用程序分离到提供特定功能的无关联的层的很自然的方法. view 层处理用户交互. model 层处理用户创建的或从外部获取的数据. controller 提供一种封装各层之间复杂交互的机制. 最后, service 层提供一种和外界(比如远程服务 API或文件系统)交互的独立机制.
组织 
通过这种分离我们自然获得一个组织水平. 每个项目都需要某个组织水平. 是的, 有人可以把他们所有的类都扔到顶级包下完事, 但即使是最小的项目这也是不可接受的. 当一个项目有了一定的规模就需要开始组织类文件的结构了. 当向同一个应用程序开发中增加团队成员的时候问题就更加严重了. RobotLegs 的 MVCS实现为项目描绘出一个分为四层的优雅的组织结构.
解耦