Cairngorm示例--业务逻辑如何管理视图(I)

(原文地址:http://www.blogjava.net/usherlight/archive/2006/12/27/90195.html)

当服务端或者客户端的逻辑变化后,有很多种方法来更新视图。我比较推荐使用ModelLocator策略,主要是使用Flex的绑定功能。
通常你的视图与ModelLocator的属性绑定,这些属性可以由命令或者其他的业务逻辑或者其他视图所改变。而一旦这些属性发生了变化,所有与它们绑定的视图都随之变化。
因 为很多的Cairngorm的例子都想做得浅显易懂,因此经常是简单地将这些属性做为ModelLocator中的一个暴露给外界的成员变量。而当 Cairngorm的应用变得庞大的时候,这往往是不够的。在此我将会专门针对这个问题展示一个例子。这个例子是一个股票市场的显示表。
第一次迭代:将应用运转起来
首 先看一下Cairngorm所主张的MVC模式。目前股票市场显示表将只包含一些简单的UI控制。点击“GetQuote”来派发Cairngorm事 件,调用命令来请求一个新报价。StockMarketPod.mxml中在Button的Click事件中派发Cairngorm事件。

None.gif< mx:Button  label ="Get Quote"  click ="getQuoteForSymbol();" />

相应的脚本代码:

 
None.gifimport org.nevis.cairngorm.samples.dashboard.events.GetStockQuoteEvent;                                    
None.gif
private function getQuoteForSymbol() : void
ExpandedBlockStart.gif
{
InBlock.gif    var event : GetStockQuoteEvent 
= new GetStockQuoteEvent( symbolTextInput.text );
InBlock.gif    dispatchEvent( event );
ExpandedBlockEnd.gif}

GetStockQuoteCommand响应并处理这个Cairngorm事件,请求一个业务代理类来报价。

None.gifpublic function execute( event : CairngormEvent ) : void
ExpandedBlockStart.gif
{
InBlock.gif    var symbol : String 
= GetStockQuoteEvent( event ).symbol;
InBlock.gif    var delegate : StockMarketDelegate 
= new StockMarketDelegate( this );
InBlock.gif    delegate.getQuoteForSymbol( symbol );
ExpandedBlockEnd.gif}


在实际情况中,需要进行一个远程的服务器端的调用,在Demo中,为简化起见,我注释掉了远程调用的相关代码。这里StockMarketDelegate.as只是对命令进行回调。

None.gifpublic function StockMarketDelegate( responder : Responder )
ExpandedBlockStart.gif
{
InBlock.gif    
//disabled for demo
InBlock.gif    
//this.service = ServiceLocator.getInstance().getService( "stockMarketDelegate" );
InBlock.gif
    this.responder = responder;
ExpandedBlockEnd.gif}

None.gif        
None.gif
public function getQuoteForSymbol( symbol : String ) : void
ExpandedBlockStart.gif
{
InBlock.gif    
//disabled for demo
InBlock.gif    
//var call : AsyncToken = service.getQuoteForSymbol( symbol );
InBlock.gif    
//call.resultHandler = responder.onResult;
InBlock.gif    
//call.faultHandler = responder.onFault;
InBlock.gif
    if( symbol == "fail" )
ExpandedSubBlockStart.gif    
{
InBlock.gif        responder.onFault();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gif    
{
InBlock.gif        responder.onResult();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

我们的StockMarketPod视图只需要两条消息,
1. 股票的报价
2. 错误消息
因为现在是第一次迭代过程中,处理比较简单,因此使用ModelLocator的成员来解决。

None.gifpublic var lastStockQuote : Number;
None.gif
public var stockQuoteError : String;


在此Demo中,GetStockQuoteCommand命令模拟返回相应的结果。

None.gifpublic function onResult( event : ResultEvent = null ) : void
ExpandedBlockStart.gif
{
InBlock.gif    
//simulate a result from service
InBlock.gif
    var stockQuote : Number = Math.random() * 50 + 5;
InBlock.gif    model.lastStockQuote 
= stockQuote;
InBlock.gif    model.stockQuoteError 
= "";
ExpandedBlockEnd.gif }

None.gif        
None.gif
public function onFault( event : FaultEvent = null ) : void
ExpandedBlockStart.gif
{
InBlock.gif    model.lastStockQuote 
= NaN;
InBlock.gif    model.stockQuoteError 
= "An error occured.";
ExpandedBlockEnd.gif}

None.gif

StockMarketPod视图绑定这些成员并进行一些格式化的处理。

None.gif<mx:FormItem label="Symbol">
None.gif    
<mx:Label text="{ formatQuote( model.lastStockQuote ) }"/>
None.gif
</mx:FormItem>
None.gif
<mx:FormItem>
None.gif    
<mx:Label text="{ model.stockQuoteError }"/>
None.gif
</mx:FormItem>

格式化函数的脚本

None.gifprivate function formatQuote( quote : Number ) : String
ExpandedBlockStart.gif
{
InBlock.gif    
return ( isNaN( quote ) ) ? "" : String( quote );
ExpandedBlockEnd.gif}


现在我们来进行重构并将一些功能从视图中抽取出来到一个可以进行单元测试的工具类中。

第二次迭代,创建符合需求的业务逻辑
现在我们已经有一个可以运行的最简单的应用。当你的应用变得庞大后,将会有很多的限制。你会发现你的ModelLocator非常的臃肿,以致于有时候,你都找不到你所要的成员。甚至会有命名冲突的事情发生。
一 个普通的重构方法是封装你的用例图中的成员成为一个业务对象。这个业务对象能够表达业务上下文中需要的视图信息。你可以把业务对象设计得最适合用例图的粒 度。在一个大型的应用中,你可能会设计一系列的业务对象来表达你的用例。你的视图将会绑定这些对象或者这些对象的属性上。通过这种方法, ModelLocator与其目标之间的联系更容易,开发者更容易掌握业务逻辑所包含的内容。
在这个Demo中,我们可以把astStockQuote和stockQuoteError这两个成员封装到一个业务对象中。

None.gifpackage org.nevis.cairngorm.samples.dashboard.model
ExpandedBlockStart.gif
{
InBlock.gif    
public class StockQuote
ExpandedSubBlockStart.gif    
{
InBlock.gif        [Bindable]
InBlock.gif        
public var lastStockQuote : Number;
InBlock.gif        [Bindable]
InBlock.gif        
public var stockQuoteError : String;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}


这样在ModelLocator中,我们只需要定义一个成员
public var stockQuote : StockQuote = new StockQuote ();
我们的视图也相应修改为:

None.gif<mx:FormItem label="Symbol">
None.gif    
<mx:Label text="{ formatQuote( model.stockQuote.lastStockQuote ) }"/>
None.gif
</mx:FormItem>
None.gif
<mx:FormItem>
None.gif    
<mx:Label text="{ model.stockQuote.stockQuoteError }"/>
None.gif
</mx:FormItem>
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值