Robotlegs最佳实践中文版

上传人:痛*** 文档编号:62655496 上传时间:2022-03-15 格式:DOC 页数:45 大小:335KB
收藏 版权申诉 举报 下载
Robotlegs最佳实践中文版_第1页
第1页 / 共45页
Robotlegs最佳实践中文版_第2页
第2页 / 共45页
Robotlegs最佳实践中文版_第3页
第3页 / 共45页
资源描述:

《Robotlegs最佳实践中文版》由会员分享,可在线阅读,更多相关《Robotlegs最佳实践中文版(45页珍藏版)》请在装配图网上搜索。

1、1. Robotlegs 是什么2. 依赖注入3. 使用 Injectorso SwiftSuspe nders适配器注入语法o Injector 类的映射注入o MediatorMap 类的依赖注入o Comma ndMap类的依赖注入4. The Context5. MVCS参考实现1. Context2. Con troller & Comma nds3. View & Mediators4. Model, Service and the Actor5. Model6. Service7. 框架事件8. Comma nds1. Comma nd 职责2. 触发 Comma nd3. 链接

2、 Comma nd4. 应用程序层的解耦Mediators1. Mediator 职责2. 映射一个 Mediator3. View Component的自动中介4. View Component的手动中介5. 映射主程序(contextView ) Mediator6. 访问一个 Mediator 的 View Component7. 给一个Mediator 添加事件监听8. 监听框架事件9. 广播框架事件10. 监听 View Component事件11. 通过 Mediator 访问 Model 和 Service12. 访问其它 Mediator9. M odels1. Model 职

3、责2. 映射一个 Model3. 从一个Model里广播事件4. 在一个 Model里监听框架事件10. Services1. Service 职责2. 映射一个 Service3. 在一个Service里监听框架事件4. 广播框架事件5. Service 示例Services应该实现一个接口在一个Service里解析数据Service 事件Robotlegs 是什么Robotlegs 是一个用来开发Flash, Flex,和AIR应用的纯 AS3微架构(框架).Robotlegs专注于将应用程序各层排布在一起并提供它们相互通讯的机制.Robotlegs试图通过提供一种解决常见开发问题的经过时

4、间检验的架构解决方 案来加速开发 Robotlegs 无意锁定你到框架,你的类就是你的类的样子,而且 应该很容易地切换到其他框架框架提供一个基于Model-View-Controller元设计模式的默认实现.这个实现提供一个针对应用程序结构和设计的强烈建议.虽然它确实轻微减低了你的 应用程序的便携性,不过它依然以最低限度影响你的具体类为目标.通过扩展 MVCS实现类,你可以获得很多有用的方法和属性.你不必使用Robotlegs的标准MVCS实现.你可以使用它的任意部分,或者完 全不使用它,或者使用自己的实现来适应你的需求.它是为了提供合适的参考实 现和快速开始使用Robotlegs而被包含进来

5、。依赖注入Robotlegs围绕依赖注入设计模式展开. 最简单地,依赖注入是为对象提供实例变量或属性的行为当你传递一个变量到 一个类的构造函数,你在使用依赖注入当你设置一个类的属性,你在使用依赖 注入.如果你不是使用严格的过程或线性方式编写 AS3,很可能你现在就在使用 依赖注入。Robotlegs使用基于元数据的自动依赖注入.这是为了方便开发而提供,而且 在排布应用程序并提供类和它所需要的依赖时,可以减少很多代码量虽然完全可以手动提供这些依赖,但是允许框架来履行这些职责可以减少出错的机会,并且通常可以加快编码进程。.使用 InjectorsRobotlegs 采用一种适配器(adapter)

6、机制来为框架提供依赖注入机制.默认地, 框架配备了 SwiftSuspenders注入/反射库来适合这个要求.另有SmartyPants-loC和Spring Actionscript的适配器可以使用.可能有潜在的特定需求来使用其它的依赖注入适配器,但是如果没有特别的理由,建议使用默 认的SwiftSuspenders ,因为它为Robotlegs 做了一些特别调整.SwiftSuspe nders适配器注入语法SwiftSuspe nders支持三种类型的依赖注入*属性(域)注入*参数(方法/设值)注入*构造注入 鉴于此文档的目的 , 我们将特别介绍属性注入 , 以及在 Robotlegs

7、里如何使用 .将属性注入类有两种选择 . 你可以使用未命名,或命名的注入 :Injectpublic var myDependency:Depedency; / 未命名注入 Inject(name=myNamedDependency)public var myNamedDependency:NamedDepedency; / 命名注入Robotlegs 里三处提供了注入映射 . MediatorMap, CommandMap, 和直接 通过 Injector . MediatorMap 和 CommandMap 也都是使用 Injector, 但 它们同时做了一些各自层 (tier) 所需要的

8、额外工作 . 顾名思义 , MediatorMap 用 来映射 Mediator, CommandMap 用来映射 Command, 其它所有需要被注 入的内容 (包括但不限于 Model) 都要直接使用 Injector 映射 .Injector 类的映射注入具体 Injector 类的适配器都遵照 IInjector 接口 . 这个接口为不同的依赖注入 解决方案提供了统一的 API. 本文档专注于 SwiftSuspenders, 但这些语法同样 适应于其它任何遵照 Iinjector 接口的 Injector.injector 是你应用程序里所发生的所有依赖注入的生产车间 . 它用来注入

9、框架 actor, 同时也可以用来执行你的应用程序所需要的任何其它注入 . 这包括但不 限于 RemoteObjects, HTTPServices, 工厂类 , 或者事实上任何有可能成为你 的对象所需要的依赖的类 /接口 .面是实现 IInjector 接口的类所提供的四个映射方法mapValuemapValue 用来映射一个对象的特定实例到一个 injector. 当请求一个特定的 类,使用类的这个特定实例来注入 ./ 你的应用程序中某个映射 / 配置发生的地方var myClassInstance:MyClass = new MyClass();injector.mapValue(MyC

10、lass, myClassInstance);/ 在接收注入的类中Injectpublic var myClassInstance:MyClassmapValue(whenAskedFor:Class, instantiateClass:Class, named:String = null)MyClass 的实例被创建和保留,并在被请求的时候被注入 . 当此类被请求的时 候,这个实例被用来满足这个注入请求 . 请注意很重要的一点,因为你已经手动 创建并通过 mapValue 映射了一个类实例 , 这个实例所需要的依赖将不会被自 动注入 . 你需要手动或通过 injector 注入这些依赖 :i

11、njector.injectInto(myClassInstance);这将立即为此实例提供已映射的可以注入的属性。 .mapClassmapClass 为每一个注入请求提供这个被映射的类的一个 特有 ( unique ) 实例 ./ 你的应用程序中某个映射 / 配置发生的地方injector.mapClass(MyClass);/ 在第一个接收注入的类里Injectpublic var myClassInstance:MyClass/ 在第二个接收注入的类里Injectpublic var myClassInstance:MyClass为上面的每一个注入提供 MyClass 的 特有 ( u

12、nique ) 实例来完成请求 . mapClass(whenAskedFor:Class, named:String = null) injector 提供了一个方法来实例化被映射的对象 : injector.mapClass(MyClass);var myClassInstance:MyClass = injector.instantiate(MyClass); 这提供你的对象的一个实例,并填充了此对象包含的所有被映射的注入点(injection points).mapSingleton mapSingleton 为每一个注入请求提供类的一个 单一 _(_single ) 实例 . 为所有

13、 映射提供类的单一实例确保你维护一个一致的状态并且不用担心创建被此类的 多余实例 . 这是一个被框架强制和管理的单一实例 , 而不是一个在类内部强制的 单例 (Singleton)./ 你的应用程序中某个映射 / 配置发生的地方 injector.mapSingleton(MyClass);/ 在第一个接收注入的类里Injectpublic var myClassInstance:MyClass/ 在第二个接收注入的类里Injectpublic var myClassInstance:MyClass在上面的例子里 , 两个注入请求都将由被请求类的相同实例填充 . 这个注入是被 延迟的 , 即对

14、象直到第一次被请求才被实例化 .mapSingletonOf(whenAskedFor:Class, useSingletonOf:Class,named:String = null)mapSingletonOfmapSingletonOf 在功能上非常像 mapSingleton. 它对映射抽象类和接口很 有用 , 而 mapSingleton 用来映射具体类实现/ 你的应用程序中某个映射 / 配置发生的地方injector.mapSingletonOf(IMyClass, MyClass); /MyClass implementsIMyClass/ 在第一个接收注入的类里Injectpub

15、lic var myClassInstance:IMyClass/ 在第二个接收注入的类里Injectpublic var myClassInstance:IMyClass这个注入方法对创建使用多态的更具可测性的类非常有用 . 在下面的 Service 实例 章节可以找到一个例子 .MediatorMap 类的依赖注入MediatorMap 实现 IMediatorMap 接口. IMediatorMap 提供两个方法来 将你的 mediators 映射到 view 并注册它们以便用来注入 .mapView(viewClassOrName:*, mediatorClass:Class, inj

16、ectViewAs:Class =null, autoCreate:Boolean = true, autoRemove:Boolean = true):voidmapView 接受一个视图类 , MyAwesomeWidget,或者一个视图的类全名 ,ponents:MyAwesomeWidget 作为第一个参数 . 第 二个参数是将要作为视图组件中介的 Mediator 类 . injectViewAs 内容未完 成, 最后的两个参数 autoCreate 和 autoRemove 提供方便的自动管理mediator 的布尔值开关 ./ 在你的程序里某个映射 / 配置发生的地方 media

17、torMap.mapView(MyAwesomeWidget,MyAwesomeWidgetMediator);/ 在 conntextView 的显示列表里的某个地方var myAwesomeWidget:MyAwesomeWidget = newMyAwesomeWidget();this.addChild(myAwesomeWidget); / ADDED_TO_STAGE事件被抛出 , 触发这个视图组件的中介机制这个方法使用了自动中介机制 . 手动中介, 以及对此方面更深入的内容将稍后在 Mediators 章节中介绍 .CommandMap 类的依赖注入CommandMap 类实现

18、ICommandMap 接口 , 提供一个用来将 command 映射到到触发它们的框架事件的方法 .mapEvent(eventType:String, commandClass:Class, eventClass:Class =null, oneshot:Boolean = false)你要提供给 commandMap 一个可以执行的类 , 执行它的事件类型 , 可选的这 个事件的强类型 , 以及这个 command 是否只被执行一次并且随即取消映射的 布尔值开关 .这个可选的强类型事件类用来对 Flash 平台的 magic string 事件类型系统做额 外的保护 .以避免采用相同事件

19、类型字符串的不同事件类之间的冲突./ 在你的程序里某个映射 / 配置发生的地方 commandMap.mapEvent(MyAppDataEvent.DATA_WAS_RECEIVED, MyCoolCommand, MyAppDataEvent);/ 在事件被广播的另外一个框架 actor 里/ 这触发了随后被执行的被映射的 commanddispatch(new MyAppDataEvent(MyAppDataEvent.DATA_WAS_RECEIVED, someTypedPayload)The ContextContext 是所有 Robotlegs 具体实现的中心 . 一个 Con

20、text, 或者也许多个Context, 提供其它层进行通讯的机制 . 一个应用程序并非只能使用一个Context, 但大多情况下一个 Context 就足够了 . 如果在 Flash 平台上创建模 块化应用程序 , 多个 Context 就是必须的了 . Context 在一个应用程序里有三 个功能:提供初始化,de-initialization-非初始化?,和用来通讯的事件中心bus.package org.robotlegs.examples.bootstrap import flash.display.DisplayObjectContainer;import org.robotleg

21、s.base.ContextEvent;import org.robotlegs.core.IContext;import org.robotlegs.mvcs.Context;public class ExampleContext extends Context implementsIContextpublic functionUnionChatContext(contextView:DisplayObjectContainer)super(contextView);override public function startup():void/ 这个 Context 只映射一个 comma

22、nd 到 ContextEvent.STARTUP 事件 ./ 这个 StartupCommand 将映射其它将在应用程 序里使用的的 command,/mediator, service, 和 ma ndM ap.mapEve nt( Con textEve nt.STARTUP,StartupComma nd. Con textEve nt, true );/启动应用程序(触发StartupCommand)dispatch( newCon textEve nt(C on textEve nt.STARTUP);MVCS参考实现Robotlegs装备了一个参考实现.这个实现遵照经典的Mode

23、l-View-Controller (MVC)元设计模式,另外增加了第四个叫做 Service的actor.这些层在本文档中通称为核心actor,或者简称为actor.MVCS提供一个应用程序的框架概况.通过将几个经过时间检验的设计模式整 合到一个具体实现,Robotlegs 的MVCS实现可以用做创建你的应用程序的 一致方案.通过这些架构概念着手一个应用程序,你甚至可以在开始你的设计之 前避免很多常见的障碍:*分离组织解耦分离MVCS提供一种将你的应用程序分离到提供特定功能的无关联的层的很自然的 方法.view层处理用户交互.model层处理用户创建的或从外部获取的数据. controlle

24、r 提供一种封装各层之间复杂交互的机制.最后,service层提供一种 和外界(比如远程服务 API或文件系统)交互的独立机制.组织通过这种分离我们自然获得一个组织水平.每个项目都需要某个组织水平.是的, 有人可以把他们所有的类都扔到顶级包下完事,但即使是最小的项目这也是不可接受的.当一个项目有了一定的规模就需要开始组织类文件的结构了.当向同一个应用程序开发中增加团队成员的时候问题就更加严重了. RobotLegs的MVCS实现为项目描绘出一个分为四层的优雅的组织结构.解耦Robotlegs的MVCS实现将应用程序解耦为4层.每层都与其它层隔离,使分 离类和组件分别测试变得非常容易.除了简化测

25、试进程,通常也使类更具便携性 以在其它项目中使用.比如,一个连接到远程 API的Service类可能在多个项 目中都很有用.通过解耦这个类,它可以不需重构便从一个项目转移到另一个中 使用. 这个默认实现只是充作最佳实践建议的一个例子 . Robotlegs 并不打算以任何 方式束缚你到这个例子 , 它只是一个建议 . 你可以随意开发自己的实现来适应你 喜欢的命名规范和开发需求 . 如果这正是你所追求的 , 请一定告诉我们 , 因为我 们一直对新方案很感兴趣 , 而且它有可能作为一种替代实现包含到 RobotLegs 的代码仓库中 .Context像 RobotLegs 中的其它实现一样 , M

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

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

28、ew 由 Mediator 类体现 . 继承 Mediator 的类用来处理框架和 View Component 之间的交互 . 一个 Mediator 将会监听框架事件和 View Component 事件, 并在处理所负责的 View Component 发出的事件时发送 框架事件 . 这样开发者可以将应用程序特有的逻辑放到 Mediator, 而避免把 View Component 耦合到特定的应用程序 .Model, Service and the ActorMVCS 架构里的 service 和 model 在概念上有着非常多的相似之处 . 因为这 种相似性 , model 和 se

29、rvice 继承了同样的 Actor 基类 . 继承 Actor 基类可 以获得很多应用程序架构内的功能 . 在 MVCS 的 context 里, 我们通过利用 继承 Actor 基类来定义应用程序所需要用来管理数据以及和外界通讯的 model 和 service 类. 本文档将把 model 和 service 类分别叫做 Model 和 Service.澄清一点 , 本文档把体现应用程序四个层的所有类都称为 framework actor 或 actor. 请不要和本例中包含的只被 Model 和 Service 类继承的 MVCS 类 Actor 混淆 .ModelModel 类用来在

30、 model 层对数据进行封装并为其提供 API. Model 会在对 数据模型进行某些工作之后发出事件通知 . Model 通常具有极高的便携性 .Service一个 service 层的 Service 用来和 外面的世界 进行通讯 . Web service, 文件 存取, 或者其它任何应用程序范围之外的行为对 service 类都很适合 . Service 类在处理外部事件时会广播系统事件 . 一个 service 应该封装和外部服务的交 互且具有非常高的便携性 .框架事件Robotlegs 使用 Flash 的原生事件用于框架 actor 之间的通讯 . 自定义事件类 通常用于此用途

31、 , 虽然使用现有的 Flash 事件同样可行 . Robotlegs 不支持事 件冒泡 , 因为它并不依赖 Flash 显示列表作为 event bus. 使用自定义类允许 开发者通过给事件添加属性来为框架 actor 之间通讯所用的系统事件提供强类 型的负载 .所有的框架 actor 都可以发送事件 : Mediator, Service, Model, 和 Command. Mediator是唯一接收框架事件的 actor. Command 是在对框架事件的处理中被触发 . 一个事件既可以被一个 Mediator 接收 , 也可以触发一 个 command.model 和 service

32、 不应该监听和处理事件 . 这样做会把它们紧耦合到应用程序 特有逻辑而降低潜在的便携性和复用性CommandCommand 是短生命周期的无状态对象 . 它们在被实例化和执行之后立即释放 Command 应该只在处理框架事件时被执行 , 而不应该被任何其他框架 actor 实例化或执行 .Command 职责Command 被 Context 的 CommandMap 注册到 Context.CommandMap 在 Context 和 Command 类里默认可用 . Command 类被 注册到 Context 时接收 4 个参数 : 一个事件类型 ; 响应这个事件时执行的 Command

33、 类; 可选的事件类 ; 一个是否该 Command 只被执行一次随即被 取消注册而不响应后续事件触发的一次性设置 .触发 CommandCommand 被 Mediators, Services, Models,和其它 Command 广播的框架事件触发 . 典型的 , 触发这个 Command 的事件会被注入到这个Command, 以提供对其属性 / 负载的访问 :public class MyCommand extends CommandInjectpublic var event:MyCustomEvent;Injectpublic var model:MyModel;override

34、 public function execute():voidmodel.updateData( event.myCustomEventPayload )一个被映射的 command 在响应一个框架事件时被实例化 , 所有已被映射 , 并 被 Inject 元数据标签标记过的依赖都会被注入到这个 Command. 另外 , 触 发这个 Command 的事件实例也会被注入 . 当这些依赖被注入完毕 , Command 的执行方法会被自动调用 , Command 便会进行它的工作 . 你不需 要, 而且不应该直接调用 execute() 方法 . 这是框架的工作 .链接 Command链接 co

35、mmand 也是可行的 :public class MyChainedCommand extends CommandInjectpublic var event:MyCustomEvent;Injectpublic var model:MyModel;override public function execute():voidmodel.updateData( event.myCustomEventPayload )/UPDATED_WITH_NEW_STUFF 触发一个 command 的 同时被/ 一个 mediator 接收然后更新一个 View Component, 但 是只在需要这

36、个响应的时候if(event.responseNeeded)dispatch( newMyCustomEvent( MyCustomEvent.UPDATED_WITH_NEW_STUFF, model.getCalculatedResponse() ) )使用这种方法可以把需要的任意多的 Command 链接在一起 . 上面的例子使 用了一个条件语句 . 如果条件不满足 Command 就不会被链接 . 这为你的 Command 执行应用程序工作提供了极大的灵活性 .应用程序层的解耦Comma nd 是解耦一个应用程序里各个 actor的非常有用的机制.因为一个Comma nd 永远不会被

37、Mediator, Model 或者Service实例化或执行,这些 类也就不会被耦合到 comma nd,甚至都不知道comma nd 的存在.为了履行它们的职责,Comma nd 可能:* 映射 Mediator, Model, Service, 或者 Con text 里的其它 Comma nd广播可能被Mediator 接收或者触发其它Comma nd 的事件.被注入Model, Service, 和Mediator 以直接进行工作.需要注意的是,不建议在一个 Comma nd 里直接和 Mediator 交互.虽然这 是可行的,但会将这个 Mediator 耦合到这个 Comma n

38、d.因为Mediator不像Service和Model,它可以接受系统事件,更好的做法是让 Comma nd 广播事件,然后让需要响应这些事件的 Mediator监听它们.MediatorMediator 类用来作为用户交互和系统的 View Component 之间的中介.一 个Mediator 可以在多个级别的粒度上履行它的职责,中介一个应用程序整体 和它的子组件,或者一个应用程序的任何和所有子组件.Mediator 职责Flash, Flex和AIR应用程序为富视觉用户界面组件提供了无限的可能.所有这些平台都提供了一套组件,像DataGrid, Button, Label 和其它常用的U

39、I组 件 . 也可以继承这些基本的组件来创建自定义组件 , 创建复合组件 , 或者完全重 写新的组件 .一个 View Component 是任何的 UI 组件和 / 或它的子组件 . 一个 View Component 是已被封装的 , 尽可能多地处理自己的状态和操作 . 一个 View Component 提供一个包含了事件 , 简单方法和属性的 API, . Mediators 负责 代表它所中介的 View Component 和框架交互 . 这包括监听组件及其子组件的 事件, 调用其方法, 和读取/设置组件的属性 .一个 Mediator 监听它的 View Component 的事

40、件 , 通过 View Component 暴露的 API 访问其数据 . 一个 Mediators 通过响应其它框架 actor 的事件并对自己的 View Component 进行相应修改来代表它们 . 一个 Mediator 通过转发 View Component 的事件或自己向框架广播合适的事件 来通知其它的框架 actor.映射一个 Mediator任何可以访问到 mediatorMap 实例的类都可以映射 Mediator. 这包括 Mediator, Context, 和 Command 类.这是映射一个 mediator 的语法 :mediatorMap.mapView( Vi

41、ewClass, MediatorClass, autoCreate, autoRemove );View Component 的自动中介 当映射一个 view component 类以获得中介时 , 你可以指定是否自动为它创 建 Mediator. 当此项为 true 时 context 将监听这个 view component 的 ADDED_TO_STAGE 事件 . 当收到这个事件这个 view component 会被自动 中介 , 它的 mediator 就可以开始发送和接收框架事件了 .View Component的手动中介有时候可能不希望或者不可能使用 view compone

42、nt 的自动中介 . 在这种情 况下可以手动创建一个 Mediator 类的实例 :mediatorMap.createMediator(contextView);这里假设这个 view component 之前已经被 mediatorMap 的 mapView() 方法映射过了 .映射主程序 (contextView ) Mediator映射 contextView 到一个 mediator 是一个常见的模式 . 这是个特殊情况 , 因为自动中介对 contextView 不起作用 , 因为它已经被添加到舞台上 , 而不会 再发出 mediatorMap 自动中介所需要的事件了 . 这个映射

43、通常在持有 contextView 引用的 Context 的 setup() 方法里完成 :override public function startup():voidmediatorMap.mapView(MediateApplicationExample,AppMediator);mediatorMap.createMediator(contextView);contextView 并没有被完全中介 , 还可以发送和接受框架事件 .访问一个 Mediator 的 View Component当一个 View Component 在一个 Context 的 contextView 里被添

44、加到舞 台上的时候 , 它默认地会被根据 MediatorMap 做映射时的配置被自动中介 . 在一个基本的 mediator 里, viewComponent 会被注入为被中介的 view component. 一个 Mediator 的 viewComponent 属性是 Object 类型的 . 在大多数情况下 , 我们希望访问一个强类型的对象以从中获益 . 为此目的 , 我们 注入被中介的 view component 的强类型实例 :public class GalleryLabelMediator extends Mediator implementsIMediatorInject

45、public var myCustomComponent:MyCustomComponent;/* 覆写 onRegister 是添加此 Mediator 关心的任何系统或 View Component 事件的好机会 .*/override public function onRegister():void/ 添加一个事件监听器到 Context 来监听框架事件 eventMap.mapListener( eventDispatcher,MyCustomEvent.DO_STUFF, handleDoStuff );/ 添加一个事件监听器到被中介的 view componenteventMap

46、.mapListener( myCustomComponent,MyCustomEvent.DID_SOME_STUFF, handleDidSomeStuff)protected function handleDoStuff(event:MyCustomEvent):void/ 把事件的强类型负载设置到 view component 的属性 ./View component很可能基于这个新数据管理自己的状态myCustomComponent.aProperty = event.payloadprotected functionhandleDidSomeStuff(event:MyCustom

47、Event):void/ 把这个事件转发到框架dispatch(event)通过这种方法我们现在可以很方便地访问被中介的 view component 的公开 属性和方法 .给一个 Mediator 添加事件监听事件监听器是 Mediator 的眼睛和鼻子 . 因为框架内的所有通讯都通过原生的 Flash 事件 , Mediator 可以通过添加事件监听器来响应感兴趣的事件 . 除了框 架事件 , Mediator 同时监听所中介的 view component 的事件 .通常在 Mediator 的 onRegister 方法里添加事件监听 . 在 Mediator 生命 周期中的这个阶段

48、, 它已经被注册并且它的 view component 和其它依赖也 都已被注入 . 具体的 Mediator 类必须覆写 onRegister 方法 . 也可以在其它 方法里添加事件监听 , 比如响应框架事件和 view component 事件的事件处 理方法里 .Mediators 装备了一个有 mapListener() 方法的 EventMap. 这个方法注册 每个被添加到 Mediator 的事件监听 , 并且确保 mediator 被框架取消注册时 删除这些事件监听 . Flash 里删除事件监听是很重要的 , 因为如果一个类里添加 了事件监听而没有删除 , Player 将无法

49、对此类进行运行时垃圾回收 (GC, Garbage Collection). 也可以使用传统的 Flash 语法添加事件监听器 , 但要注 意也要手动把它们删除监听框架事件 所有框架里的 actor 在实例化时都会被注入一个 eventDispatcher 属性 . 这个 eventDispatcher 就是 Mediator 发送和接受框架事件的机制 .eventMap.mapListener(eventDispatcher, SomeEvent.IT_IS_IMPORTANT, handleFrameworkEvent)通过此语法 , 一个 Mediator 现在监听了 SomeEvent

50、.IT_IS_IMPORTANT 事 件并在 handleFrameworkEvent 方法里处理它 .广播框架事件Mediator 的一个很重要的职责就是向框架发送其它 actor 可能感兴趣的事件 . 这些事件通常是在响应应用程序用户和被中介的 view component 之间的一 些交互时发出的 . 这里同样有一个可以减少发送事件到框架的代码输入的很有 用的方法 :dispatch(new SomeEvent(SomeEvent.YOU_WILL_WANT_THIS, myViewComponent.someData)这个事件现在可以被其它 Mediator 接收或者执行一个 comm

51、and 了. 发出 事件的 Mediator 并不关心其它的 actor 如何回应这个事件 , 它只是简单地广 播一条有事发生的消息 . 一个 mediator 也可以监听自己发出的事件 , 然后据 此作出回应 .监听 View Component事件Mediator 负责所中介的view component 发出的事件.这可以是个独立组件 比如TextField或者Button,也可以是有嵌套层级的复杂组件.当mediator 收到view comp on e nt发出的事件会使用指定的方法处理它.和框架事件一样,EventMap 的mapListener 方法是给一个mediator 添加

52、事件监听的首 选.eve ntMap.mapListe ner(myMediatedViewComp onent,SomeEve nt.USER_DID_SOMETHING, ha ndleUserDidSomethi ngEve nt)响应一个 view component的事件时, 一个 mediator 可能:*考察事件的负载(如果有) 考察view component的当前状态* 对view component进行需要的工作发送系统事件以通知其它actor有事发生通过 Mediator 访问 Model 和 Service你的mediator 可以监听Service和Model类派出的

53、系统事件来提高松耦 合性.通过监听事件,你的mediator不需要关心事件来源,而只需直接使用事 件携带的强类型的负载.因此,多个mediator 可以监听相同的事件然后根据 所收到的数据调整自己的状态在一个 mediator 里直接访问 service 可以提供很大便利而不会带来严重的 耦合性问题 . 一个 service 并不存储数据 , 只是简单地提供一个向外部 service 发送请求并接受响应的 API. 能够直接访问这个 API 可以避免在你的应用程序中 增加不需要的 command 类来达到同样目的 . 如果这个 service API 在很多 mediator 中通过相同的方式

54、访问 , 将此行为封装到一个 command 里有益于 保持此行为的一致性并减少对此 service 的反复调用以及在你的 mediator 里的直接访问 .建议通过 model 和 service 实现的接口将 model 和 service 注入 mediator. 下面的 Service 实例 章节可以找到一个这样的例子 .访问其它 Mediator如同 Service 和 Model, 在一个 Mediator 里也可以注入和访问其它的 Mediator. 这种做法是 强烈不建议的 因为这种紧耦合可以简单地通过使用框 架事件进行通讯而避免 .ModelModel 类用来管理对应用程序的

55、数据模型的访问 . Model 为其它框架 actor 提 供一个 API 来访问 , 操作和更新应用程序数据 . 这个数据包括但不限于原生数 据类型比如 String, Array, 或者像 ArrayCollection 一样的域特有对象或集 合.Model 有时被当做简单的 Model 比如 UserModel, 有时也被当做 Proxy比如 UserProxy. 在 Robotlegs 里, 这两种命名都是用作相同的目的 , 为应用 程序数据提供一个 API. 不管采用哪种命名 model 都继承提供了核心框架依 赖和一些有用方法的 Actor 基类 . 本文档将这些类当做 Model

56、.Model 职责Model 类封装了应用程序数据模型并为其提供一个 API. 一个 Model 类是你 的应用程序数据的看门人 . 应用程序里的其它 actor 通过 Model 提供的 API 请求数据 . 因为数据是通过 Model 更新, Model 装备了向框架广播事件的机 制以向其它 actor 通知数据模型的变化使它们得以据此调整自己的状态 .除了控制对数据模型的访问 , Model 通常也被用来保证数据状态的有效性 . 这 包括对数据进行计算 , 或域特有逻辑的其它领域 . Model 的这个职责非常重要 . Model 是应用程序中最有潜力具有便携性的层 . 通过把域逻辑放入

57、 Model, 以后的 model 实现就不再需要像把域逻辑放入 View 或 Controller 层那样 重复这些相同的逻辑 ,作为一个例子 , 你的 Model 里可能执行购物车数据的计算 . 一个 Command 将会访问这个方法 , 最终的计算结果将会被作为被某个 Mediator 监听的事件 派发出去 . 这个 mediator 将会根据这个被更新的数据更新自己的 view component, 应用程序的第一个迭代是个典型的 Flex 程序 . 这个计算也很容 易在一个 Mediator 甚至视图里进行 . 应用程序的第二个迭代是一个需要全新 视图元素的移动设备 Flash 应用

58、程序 . 因为这个逻辑在 Model 里, 所以可以 很容易被两个完全不同元素的视图复用 .映射一个 ModelInjector 有几个方法可以用来将你的 Model 类映射到你的框架 actor. 另外 ,这些方法事实上可以用来注入任何类到你的类里 . 将一个已存在的实例当做一个单例注入映射 , 使用下面的语法 : injector.mapValue(MyModelClass, myModelClassInstance) 为每个注入映射一个类的新实例 , 使用下面的语法 : injector.mapClass(MyModelClass, MyModelClass)另外 , 这也可以用来使用被

59、注入的实现某接口的合适的类来映射这个用来注入 的接口.injector.mapClass(IMyModelClass, MyModelClass) 为某个接口或类映射一个单例实例 , 使用下面的语法 : injector.mapSingleton(MyModelClass, MyModelClass) 需要注意重要的一点 , 当提及上面的一个单例时 , 它并不是一个单例模式的单例 在这个 Context 之外并不强制它作为一个单例 . Injector 简单地确保这个类的 唯一一个实例被注入 . 这对处理你的应用程序数据模型的 Model 非常重要 .从一个Model里广播事件Model类提供

60、一个方便的dispatch方法用来发送框架事件:dispatch( newImporta ntDataEve nt(lmporta ntDataEve ntMPORTANT_DATA_UPDATED)有很多理由派发一个事件,包括但不限于:数据已被初始化并准备好被其它actor使用一些数据片被添加到 Model*数据被从Model中删除数据已改变或者更新*数据相关的状态已改变在一个Model里监听框架事件虽然技术上可能,但强烈不建议这样做不要这样做只是为了说清楚:不要这样做.如果你这样做了,不要说你没被警告过.ServiceService用来访问应用程序范围之外的资源.这包括但当然不限于:* w

61、eb services*文件系统数据库 RESTful APIs 通过localConnection的其它 Flash应用程序Service圭寸装了这些和外部实体的交互,并管理这个交互产生的 result , fault 或其它事件你可能注意到Service和Model的基类非常相像.事实上,你可能注意到除 了类名,它们其实是一样的.那么为什么用两个类呢? Model和Service类在 一个应用程序里有完全不同的职责.这些类的具体实现将不再相像.如果没有这 个分离,你将经常发现 Model类在访问外部服务.这让Model有很多职责, 访问外部数据,解析结果,处理失败,管理应用程序数据状态,为

62、数据提供一个 API,为外部服务提供一个 API,等等.通过分离这些层有助于缓解这个问题.Service 职责一个Service类为你的应用程序提供一个和外部服务交互的API. 一个service类将连接外部服务并管理它收到的响应.Service类通常是无状态的实 体.他们并不存储从外部服务收到的数据,而是发送框架事件来让合适的框架 actor管理响应数据和失败.映射一个Service有injector的多个可用的方法可以用来映射你的Service类以注入你的其它 框架actor.另外,这些方法也可以用来注入事实上任何类到你的类里.将一个已存在的实例当做一个单例注入映射 , 使用下面的语法 :

63、injector.mapValue(MyServiceClass, myServiceClassInstance) 为每个注入映射一个类的新实例 , 使用下面的语法 : injector.mapClass(MyServiceClass, MyServiceClass)另外 , 这也可以用来使用被注入的实现某接口的合适的类来映射这个用来注入 的接口.injector.mapClass(IMyServiceClass, MyServiceClass) 为某个接口或类映射一个单例实例 , 使用下面的语法 : injector.mapSingleton(MyServiceClass, MyServiceClass) 需要注意重要的一点 , 当提及上面的一个单例时 , 它并不是一个单例模式的单例 在这个 Context 之外并不强制它作为一个单例 . Injector 简单地确保这个类的 唯一

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!