flex 框架 Cairngorm 中Command、Delegate、Service交互详解

Command、Delegate、Service这三者的关系简单说来就是前者调用后者,后者为前者返回数据的关系!
让我们以参考资料中的源码为例详细描述一下:
Command的源代码如下,类名叫:GetProductsCommand

package com.adobe.cairngorm.samples.store.command
{
        import mx.rpc.IResponder;
        import com.adobe.cairngorm.commands.ICommand;
        import com.adobe.cairngorm.control.CairngormEvent;
        import com.adobe.cairngorm.samples.store.business.ProductDelegate;
        import com.adobe.cairngorm.samples.store.model.ShopModelLocator;
        import com.adobe.cairngorm.samples.store.util.Comparator;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;
        import mx.controls.Alert;
        import mx.collections.ICollectionView;
        import mx.collections.Sort;
        import mx.collections.SortField;
        import mx.utils.ArrayUtil;
       
        public class GetProductsCommand implements ICommand, IResponder
        {
               public function execute( event : CairngormEvent ): void
               {
                  if( ShopModelLocator.getInstance().products == null )
                  {
                      var delegate : ProductDelegate = new ProductDelegate( this );
                      delegate.getProducts();
                   }
                   else
                   {
                        Alert.show( "Products already retrieved!" );
                        return;
                    }
               }
              
               public function result( event : Object ) : void
               {      
                 //result()方法从表现服务器结果的event 中提
                 // products数组并将它们保存在 ShopModelLocator中,
                 //同时将 selectedItem 设置为产品列表中的第一个产品。
                 var products : ICollectionView = ICollectionView( event.result );
                 var model : ShopModelLocator = ShopModelLocator.getInstance();
                 // sort the data。
                 var sort :Sort = new Sort();
                 sort.fields = [ new SortField( "name", true ) ];
                 products.sort = sort;
                 products.refresh();
                // set the products on the model
                 model.selectedItem = products[ 0 ];
                 model.products = products;
                 model.workflowState = ShopModelLocator.VIEWING_PRODUCTS_IN_THUMBNAILS;
               }
              
               public function fault( event : Object ) : void
               {
                  var faultEvent : FaultEvent = FaultEvent( event );
                  Alert.show( "Products could not be retrieved!" );
               }
        }
 }

注意代码中的这一行:

var delegate : ProductDelegate = new ProductDelegate( this );

这里将GetProductsCommand类的实例作为参数(this)传递给ProductDelegate的构造函数,这样做就是告诉Delegate,该Command将处理所有通过Dlegate发送的请求所返回的结果。在Delgate中,这个接收所有返回结果的Delegate成为Responder。如下Delegate的源码(ProductDelegate.as)中可以看到:

package
com.adobe.cairngorm.samples.store.business
{
        import mx.rpc.IResponder;
        import com.adobe.cairngorm.business.ServiceLocator;
        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.AbstractOperation;
 
        public class ProductDelegate
        {
               //构造函数的参数为IResponder类,将接受所有请求的返回结果
               public function ProductDelegate( responder : IResponder )
               {             
                       this.service = ServiceLocator.getInstance().getRemoteObject( "productService" );
                       this.responder = responder;
               }

               public function getProducts() : void
               {                     
                       //调用Service,这两行代码可以作为模板, 在其他Cairngorm应
                       //用中写法也是一样的!这两行代码确保了从服务器返回的
                       //
results 和faults都能返回给Delegate。
                       var call : Object = service.getProducts();

                       call.addResponder( responder );
               }
               private var responder : IResponder;
               private var service : RemoteObject;
        }
}

从第一段代码中可以看到,Command类实现了ICommand和 IResponder两个接口,当它选择扮演responder的角色,Command实现FLEX定义的IResponder接口;这确保了开发者可以添加一个result()犯法来处理任何Delegate结果,一个fault()方法来处理所有Delegate的错误。

整个工作流程可以描述如下:

1、Command类产生一个业务代理(delegate)的实例;
2、Command类调用delegate中的业务处理方法,上例中为getProducts();
3、Delegate查找到service,并调用service;
4、过了一会,服务器返回结果给delegate;
5、Delegate立即将结果传给command的result()方法或者调用command的fault()方法。

通过这个机制的运用,一方面使得Delegate可以被重用,另一方面将服务器端调用进行了封装,delegate变成了客户端代码和服务器端代码的唯一接口。这样做也为客户端和服务器端代码分别开发提供了可能(我们在写客户端程序是不一定服务器端程序已经就绪,只需要它提供一些静态试验数据(或称为为数据:dummy data)即可)。


==================================================
参考资料:
1)Developing Flex RIAs with Cairngorm microarchitecture – Part 5: Server-side integration

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值