为框架初学者准备的RobotLegs
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为框架初学者准备的RobotLegs
flash, injector, robotlegs
本帖最后由chocoZero 于 2010-6-10 20:15 编辑
最近我试验了很多微架构框架。作为一个框架新手,我觉得把过程中的想法分享出来对大家都是有好处的。上次,我对付了Mate。这次,我在玩Robotlegs了。
首先我想表示对Joel Hooks的感谢,我是在360|Flex认识他的,他当时正在进行RobotLegs 培训的演示。那时我还不完全懂他说的东西,一直到后来亲身体验才明白,Joel在过程中给了很大的帮助和支持,从解决我打开RobotLegs网站不畅的问题到回答我不时的提问等等。
从RobotLegs开始
你要做的第一件事就是到去下载最新版本。你会得到一个zip文档,其中包括了RobotLegs的源代码,它的api文档,还有两个swc,一个在bin文件夹,另一个在libs文件夹。
在bin文件夹下的就是RobotLegs框架,而在libs文件夹下的那个同样重要。swc是SwiftSuspenders,用来提供Robotlegs默认使用的injector。稍后解释所谓的默认injector。现在,你主要需要知道的是要使用RobotLegs,就要把这些swc都放在你的Flex项目的libs文件夹下。
就算提供了RL的源代码,使用swc也是重要的,因为它所做的就是确定框架使用的元数据编译进你的代码而不是丢弃它,这也是编译器默认要做的事情。
RobotLegs里的Context
对于我来说,在RL里需要明白的最重要的概念是Context是什么以及它做什么。Context Class 是把所有其他元素粘在一起的某种“胶水”。它实例化了一个EventDispatcher,就是所有默认的MVCS接口里的类都有用到的那个。
什么是默认的MVCS应用?
很高兴你问这个问题。RobotLegs定义了几乎接口方面的所有东西,也就是说RobotLegs里用的类可以用其他能实现相同接口的类替代。所以,理论上,你可以创建完全不同的RobotLegs
应用。
默认的RobotLegs注射器把我带回到SwiftSuspenders。事实上,它确实是默认的IInjector,因为RobotLegs完全没有定义一个injector类。你可以使用其他的loC框架,好像SmartyPants(不过你可能需要写些adapter代码来使它生效)
SwiftSuspenders是写来专门支持RobotLegs的,当你使用它作为你的IContext类的时候,Context类将为你创建一个SwiftSuspenders Injector。这个Injector无疑储存在名为injector的保护属性里,你可以在继承Context类的时候使用。
Injector是干嘛的?
我说过,使用swc有助于确保Flex/Flash Builder编译器能留住RobotLegs和SwiftSuspenders需要的元数据。当你在声明之前增加了[Inject]的元数据标签,而RobotLegs 和那个类也有互动的话,Injector会检查它的“小黑皮书”看有没有声明所需要的任何类型的对象,之后该对象会被注入,通常是作为一个变量值的形式。如果没有那个类型的对象存在,它会做一个出来。
就算你对Injector什么都不做,Context也会在它的“黑皮书”里为你增加一些项目,比如它做的EventDispatcher和对Injector自身的引用。认识到整个规划很重要,某种程度上你不会不小心干扰到它们。你也可以以默认MVCS类接口利用他们,就像Actor和Mediator的关系。
RobotLegs有两种途径和类实例互动以注入值
首先,它可以通过多种方式创建实例。例如,如果你写了injector.mapSingleton(YourClass),然后这个injector需要把一个“YourClass”作为一
个属性注射进其他类里,它将会创建一个YourClass。如果YourClass有任何[inject]标
签,当新YourClass创建出来的时候将被填充。
第二个方式是Context的构造函数采用了DisplayObjectContainer的一个参数,它将定
义Context是谁的Context。Context为ADDED_TO_STAGE的事件增加了事件监听器,
所以当新的视图组件被加进来的时候,Context将检查图纸以确定是否需要做些什么。你
可能会说:“ADDED_TO_STAGE又不会出声,那怎么可能?”实际上你可以设置useCapture标示为真,并监听这个“正在途中”的事件,就像从前一样。
尽管如此,主要还是要记住Context将会因任何DisplayObjectContainer的子或孙的增
加而标记。在这一点上,它既可以注入到新建的对象,也可以创建一个过渡对象来进行注入。
这里将给你RobotLegs里数据如何移动的粗略概念,其实更多的是程序如何工作的概念。
在RobotLegs里启动
Context设置了一个命令路线图(CommandMap),也就是说,“当Context的EventDispatcher发送了一个事件X,就创建命令Y的一个实例并执行它的execute()方法。”
什么是Command?
一个Command基本上就是一个用来执行一套命令来完成单独目标的短期对象。这个command将接收任何它需要的对象/信息来用和RobotLegs实例化时一样的方式执行那些命令——被Injector注射。这包括了对Context里eventDispatcher和injector属性的引用。
使用RobotLegs让我认识到自己曾有严重的偏见,认为类是某个东西。这样想的后果就是,它可能也做事,其实它的主要目标是“成为什么”,而不是“要去做什么”。一旦我把偏见摆一边,我完全爱上了命令模式和命令图。它代码化你选择发送的每一个事件内容,允许使用很有可读性的代码(下载不可用)。
我通常会注释代码,但我在新的适应RobotLegs例子的代码里却几乎没有注释。注释不再必要,因为Command的名字(例如GetTaxonomyRoot,AttachChildrenToModel)清楚的说明了当给定事件触发时会发生什么。
对于我来说,最难的部分是认出切入点(哪个事件插入进程中然后哪个Command应该先执行)。幸运的是,我还有在360|Flex训练时的文件,我用了Joel在他的Context里相同的事件(ContextEvent.STARTUP),经过小的试验我找出了我的哪一个Command先用才对。
一个Command可以做什么?
一般的,Command有途径接触到Context的commandMap,Context联结的DisplayObjectContainer,EventDispatcher,injector和我还没提过的Context的另一个属性mediatorMap。这就是说它们可以加其他的Commands进CommandMap里,增加监听器进DisplayObjectContainer,发送事件到框架,为injector规划更多类。而且,它们也有途径让你通过使用[Inject] 元数据选择其他信息给它们。这就帮你扩展了更多的可能性。
有一类数据注入Command比较困难——如果不是不可能的话——那就是加载到Context 使用的显示列表的对象。我们已经知道我们可以在视图组件首次加载到舞台上时注入数据,但是如果我们在程序状态变化时改变它的显示,或者想在用户和视图发生交互时在程序里标记下来呢?
用Mediator和视图通讯
RobotLegs有个东西叫做Mediator,但是我想叫它Supervising Presenter更合适些。简而言之,对于你想钓进RobotLegs里的每一个视图类,推荐你创建具有多种反应能力的