请输入您要查询的百科知识:

 

词条 Robotlegs
释义

Robotleg

Robotlegs 是一个用来开发Flash, Flex, 和 AIR应用的纯 AS3 微架构(框架).Robotlegs 专注于将应用程序各层排布在一起并提供它们相互通讯的机制. Robotlegs 试图通过提供一种解决常见开发问题的经过时间检验的架构解决方案来加速开发. Robotlegs 无意锁定你到框架, 你的类就是你的类的样子, 而且应该很容易地切换到其他框架.

框架提供一个基于 Model-View-Controller元设计模式的默认实现. 这个实现提供一个针对应用程序结构和设计的强烈建议. 虽然它确实轻微减低了你的应用程序的便携性, 不过它依然以最低限度影响你的具体类为目标. 通过扩展 MVCS实现类, 你可以获得很多有用的方法和属性.

你不必使用Robotlegs的标准 MVCS实现.你可以使用它的任意部分, 或者完全不使用它, 或者使用自己的实现来适应你的需求. 它是为了提供合适的参考实现和快速开始使用 Robotlegs 而被包含进来。

依赖注入

Robotlegs 围绕 依赖注入设计模式展开.

最简单地, 依赖注入是为对象提供实例变量或属性的行为. 当你传递一个变量到一个类的构造函数, 你在使用依赖注入. 当你设置一个类的属性, 你在使用依赖注入. 如果你不是使用严格的过程或线性方式编写AS3, 很可能你现在就在使用依赖注入。

Robotlegs 使用基于元数据的自动依赖注入. 这是为了方便开发而提供, 而且在排布应用程序并提供类和它所需要的依赖时,可以减少很多代码量. 虽然完全可以手动提供这些依赖, 但是允许框架来履行这些职责可以减少出错的机会,并且通常可以加快编码进程。.

使用 Injector

Robotlegs 采用一种适配器(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实现为项目描绘出一个分为四层的优雅的组织结构.

解耦

Robotlegs 的MVCS实现将应用程序解耦为4层. 每层都与其它层隔离, 使分离类和组件分别测试变得非常容易. 除了简化测试进程, 通常也使类更具便携性以在其它项目中使用. 比如, 一个连接到远程 API的 Service 类可能在多个项目中都很有用. 通过解耦这个类, 它可以不需重构便从一个项目转移到另一个中使用.

这个默认实现只是充作最佳实践建议的一个例子. Robotlegs 并不打算以任何方式束缚你到这个例子, 它只是一个建议. 你可以随意开发自己的实现来适应你喜欢的命名规范和开发需求. 如果这正是你所追求的, 请一定告诉我们, 因为我们一直对新方案很感兴趣, 而且它有可能作为一种替代实现包含到 RobotLegs 的代码仓库中.

Context

像 RobotLegs 中的其它实现一样, MVCS实现也是围绕一个或多个 Context. 这个 context 提供一个中心的事件 bus 并且处理自己的启动和关闭. 一个 context 定义了一个范围. 框架 actor 们处在 context 之内,并且在 context 定义的范围之内进行相互间的通讯. 一个应用程序是可以有多个 context 的. 这对想要加载外部模块的应用程序很有用. 因为在一个 context 里的 actor 只能在他们的 context 定义的范围之内相互通讯, 所以在一个模块化的应用程序里, 不同 context 之间的通讯是完全可能的.

本文档不讨论模块化编程的内容. 之后本文档内所有提到的 Context 都指在一个应用程序里的单一的 context.

Controller & Command

Controller 层由 Command 类体现. Command 是用来执行应用程序单一单位工作的, 无状态的, 短生命周期的对象. Command 用于应用程序各层之间相互通讯, 也可能用来发送系统事件. 这些系统事件既可能发动其它的 Command, 也可能被一个 Mediator 接收,然后对一个 View Component 进行对应这个事件的工作. Command 是封装你的应用程序业务逻辑的绝佳场所.

View & Mediator

View 由 Mediator 类体现. 继承 Mediator 的类用来处理框架和 View Component 之间的交互. 一个 Mediator 将会监听框架事件和 View Component 事件, 并在处理所负责的 View Component 发出的事件时发送框架事件. 这样开发者可以将应用程序特有的逻辑放到 Mediator, 而避免把 View Component 耦合到特定的应用程序.

Model, Service and the Actor

MVCS架构里的 service 和 model 在概念上有着非常多的相似之处. 因为这种相似性, model 和 service 继承了同样的 Actor 基类. 继承 Actor 基类可以获得很多应用程序架构内的功能. 在 MVCS的 context 里, 我们通过利用继承 Actor 基类来定义应用程序所需要用来管理数据以及和外界通讯的 model 和 service 类. 本文档将把 model 和 service 类分别叫做 Model 和 Service.

澄清一点, 本文档把体现应用程序四个层的所有类都称为"framework actor"或"actor". 请不要和本例中包含的只被 Model 和 Service 类继承的 MVCS类 Actor 混淆.

Model

Model 类用来在 model 层对数据进行封装并为其提供 API. Model 会在对数据模型进行某些工作之后发出事件通知. Model 通常具有极高的便携性.

Service

一个 service 层的 Service 用来和"外面的世界"进行通讯. Web service, 文件存取, 或者其它任何应用程序范围之外的行为对 service 类都很适合. Service 类在处理外部事件时会广播系统事件. 一个 service 应该封装和外部服务的交互且具有非常高的便携性.

框架事件

Robotlegs 使用Flash的原生事件用于框架 actor 之间的通讯. 自定义事件类通常用于此用途, 虽然使用现有的 Flash 事件同样可行. Robotlegs 不支持事件冒泡, 因为它并不依赖 Flash 显示列表作为 event bus. 使用自定义类允许开发者通过给事件添加属性来为框架 actor 之间通讯所用的系统事件提供强类型的负载.

所有的框架 actor 都可以发送事件: Mediator, Service, Model, 和 Command. Mediator 是唯一接收框架事件的actor. Command 是在对框架事件的处理中被触发. 一个事件既可以被一个 Mediator 接收, 也可以触发一个 command.model 和 service 不应该监听和处理事件. 这样做会把它们紧耦合到应用程序特有逻辑而降低潜在的便携性和复用性.

随便看

 

百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。

 

Copyright © 2004-2023 Cnenc.net All Rights Reserved
更新时间:2025/2/26 22:19:04