[Flex]AdvancED Flex 3中文翻译(四)
为本地或远程创建一个统一的model代理
当真正的对象不存在时,代理可以代替真正的对象。当一个真正的对象做一些花销很大的操作或需要一段时间才能加载时,代理代替真正的对象,直到真正的对象可以使用。代理的API和真正的对象是想同的,因些当真正的对象还在加载或初始化时,你也可以调用它。当真正的对象可用时,这个调用会传递给它,它会对调用做出反应。
代理可分为两类,虚拟代理和远程代理,虚拟代理的定义完全符合上一段所描述的。远程代码略有不同,因为它不在本地。
如果是一个远程对象,通过代理我们能象本地一样操作。调用会建立一个代理对象并且传递给真正的远程对象。当收到远程对象的答复里,代理会传递给调用者。几乎所有的语言都允许远程代理用RPC调用分布式远程对象。在这种情况下,它调用的一般是对应的结构。
为内部和外部数据建立一个统一的获取机制,我们需要一个外部数据源的远程代理接口。与此同时,在复杂的应用程序里,一些数据可能会涉及复杂的操作。通常这些复杂的操作发生在远程调用的时候。因此我们需要建立有虚拟和远程两种代理功能的代理。
从调用者的角度看,无论是调用本地还是远程,简单还是复杂的资源都是一样的。
model有不同的类型和特点,所以从对象到对象有不同的代理接口。我们定义一个名叫ImodelProxy的接口指定为model类的代理类型。这个代理类也实现了flash.events. IEventDispatcher接口,定义了添加、删除、侦听和发送事件的方法。当一个远程操作返回成功,会触发相应的事件。定义事件处理程序去处理相应的操作。
在我们的例子中,我们希望MedalWinner和MedalTally对象以相同的方式处理,无论数据是本地的还是远程的,因此我们将使用这两种代理模式。
在少数情况下,你的model会在源代码的不同的地方。在这种情况下,在应用程序中使用一个对象之前你可能想定义一个理想的对象。在这种情况下你可能需要一个外观(façade)而不是一个代理(proxy)。你仍然可以期待你的外观(façade)能有延时加载数据和表现出一些代理的一些行为。一个外观(façade)有时还可以简化复杂的ORM,在应用程序中定义一个对象之前建立数据之间的关系。
另外一些情况下,你可能不需要编写代码,但要显示出原始model的API。当你需要定义外部数据去适合你的程序model时,通常会这样做。这个时候你可能需要是适配器(adapter)而不是一个代理(proxy)或一个外观(façade)。或者你需要适配器能支持延时加载数据或代替原始数据,就像一个代理一样。
让我们改变一下那个简单的model,作为一个看起来像新结构下的一个代理那样去理解它。我们仅仅用MedalTally去控制一个XML文件的内容。在真实情况下,你会在MedalTally中包含MedalWinner对象。在1-4所示的UML图中显示了结构,一些接口和类去实现一个代理。

(1-4)
MedalTally.as的源代码和MedalTallyProxy.as实现的类在这里包括一个代理的特征。首先看一下MedalTallyProxy.as:
- package com.riarevolution.advancedflex3.examples.athens2004.model.proxy
- public class MedalTallyProxy implements IMedalTally, IModelProxy
- {
- private var _sourceData:XML;
- private var _medalTally:MedalTally;
- public function MedalTallyProxy(_sourceData:XML)
- {
- _sourceData = getSourceData();
- medalTally = new MedalTally();
- //TODO: 实现函数
- }
- public function getMedalWinners():Array
- {
- if(_medalTally.getMedalWinners() == null) {
- _medalTally.setMedalWinners(mx.utils.ArrayUtil.toArray(_sourceData.MedalWinner));
- }
- return _medalTally.getMedalWinners();
- }
- public function setMedalWinners(value:Array):void
- {
- mx.utils.ArrayUtil.toArray(_sourceData.MedalWinner) = value;
- _medalTally.setMedalWinners(value);
- }
- private function getSourceData() {
- // 实现远程代理
- // 从外部XML文件得到数据
- }
- }
- }
再看MedalTally.as:
- package com.riarevolution.advancedflex3.examples.athens2004.model.proxy{
- public class MedalTally implements IMedalTally {
- private var _medalWinners:Array;
- public function MedalTally() {
- super();
- }
- public function getMedalWinners():Array {
- return _medalWinners;
- }
- public function setMedalWinners(value:Array):void {
- _medalWinners=value;
- }
- }
- }
我们来看MedalTallyProxy.as,我们没有实现取得外部数据的方法(getSourceData)。你能使用URLLoader类来加载外部的XML文件来做为一个远程代理。特别是一个大的XML文件。
下节继续!
(转载请注明出处,请勿使用商业用途!)
继续加油哦!!!!!!!!
十分不错
谢谢分享,很不错!一定还会来的咯!