隨筆-31  評論-257  文章-0  trackbacks-0
                做Flex做久了做大了,就會覺得之前寫的的Flex代碼開始有點亂,哪怕你寫的規(guī)范了,但總覺得結(jié)構(gòu)松散,維護不方便,相信很多人剛開始做Flex的時候,都是想到什么功能,就寫什么功能,或者有些好點的,就先畫了個大體的流程圖之類的,因為現(xiàn)在Flex普及得還不夠,很多人做Flex也是試探階段,不敢用作商業(yè)項目或其它大項目,只會用來試水技術(shù)層面的,所以都是做些小應用的多,就會忽略了設計一個比較好的框架來開發(fā)。所以Flex的開發(fā)框架就應運而生了。目前,好的Flex開發(fā)框架還不多,官方有個Cairngorm的框架,可能有些人會說這個框架有點復雜,其實不然,對比起Ruby的Rails,Java的Struts,Spring之類的開發(fā)框架,就顯得簡單得多了。只要清楚了解要MVC的概念,就會對這些框架并不陌生,但是今天的主角不是Cairngorm,而是另一個Flex框架 PureMVC,如果說Cairngorm復雜的話,那么PureMVC就顯得簡單多了,PureMVC比較輕盈,核心也只有十來個類,是一個輕量級的Flex框架,但PureMVC的通用性還是比較廣的,有PHP的,有Java的有Python的。可能直接說框架的使用會比較抽象,那么就由一個實例來開始講解吧,就用一個PureMVC做的一個MP3播放器。



          先來看看PureMVC的結(jié)構(gòu)圖:



                在圖中,F(xiàn)acade,Model,View,Controller都是PureMVC的四個核心類,都是單例模式的,用戶無需操作那Model,View,Controller類,而用戶只需要操作Facade就夠了,F(xiàn)acade類用來管理其它的三個單例類,顧名思義,那三個類都是分別對應 MVC 模式的那三個元素,F(xiàn)acade也是個單例,它負責創(chuàng)建,激活,調(diào)用其它的三個類,管理MVC各屋的生命周期。
                而我們看看Model類,又細分了一個Proxy類出來,我們稱其為代理吧,就是對數(shù)據(jù)模型的一個代理,負責訪問我們的數(shù)據(jù)對象(Data Object)也就是Cairngorm中的ValueObject,其實都是同一個概念。而類結(jié)構(gòu)上,對數(shù)據(jù)操作的代理Proxy類就只有一個,但可以從我們的應用上又分為Local Proxy,Remote Proxy,其實都只是Proxy ,只是根據(jù)用戶的應用的不同,在Proxy里面實現(xiàn)不同的功能而已,比如如果你操作本地數(shù)據(jù)(內(nèi)存中的數(shù)據(jù),并非本地操作系統(tǒng)的文件),你可以寫一些VO的getter/setter直接操作數(shù)據(jù),而如果是Remote的數(shù)據(jù)的話,你可以在Proxy類里定義一些HttpService,URLLoader,WebService等等的訪問遠程數(shù)據(jù)的API,之后將獲取到的遠程數(shù)據(jù)放在VO中。
                在Controller類里分出一個叫Command的類來,直接翻譯的話,就是“命令”類,通常這些類都是用來處理一些業(yè)務流程,某些算法操作等等的操作。比如現(xiàn)在用戶單擊了“獲取數(shù)據(jù)”的按鈕,程序?qū)腜roxy類里訪問服務器,服務器返回數(shù)據(jù)之后,那些都是程序看得懂的數(shù)據(jù),比如是XML,而如果數(shù)據(jù)結(jié)構(gòu)比較復雜,你不可能直接將數(shù)據(jù)顯示給用戶看吧?那就將解析這些數(shù)據(jù)的工作交給Command來做,比如寫一個ParseCommand的類,將獲得的XML數(shù)據(jù)傳遞給該Command,在Command里進行數(shù)據(jù)的過濾,排列,整理等等的功能。再將組積好后數(shù)據(jù)交給Mediator來進行顯示,而Mediator,就是下面我們要說的。
                在View類里分出一個Mediator的類,該類是用來對ViewComponent操作的,我們暫且叫它“中介類”吧,為什么叫“中介”呢?其實就是用戶界面(UI)與程序結(jié)構(gòu)邏輯之間的中介,因為用戶在界面上的操作,比如Button的Click事件不是直接反映到Command或者Proxy類上的,而是反映給Mediator類,在Mediator里作一些簡單處理,比如驗證合法性,觸發(fā)其它ViewComponent的狀態(tài)等,在這里也會將用戶的數(shù)據(jù)封裝在VO里面,再交由Command或Proxy來進一步處理。基本上Mediator只對用戶的操作或用戶提交的數(shù)據(jù)進行封裝并簡單預處理,而業(yè)務邏輯,存儲服務的就應交給Command和Proxy來做,這樣MVC分工好,使得程序結(jié)構(gòu)比較嚴緊,可讀性強,實現(xiàn)松耦合。當你改變了UI時,只需要對Mediator進行相應的改變就行了,而你改變了業(yè)務的邏輯與算法之類的話,也相應的改變Command就可以了,對其它模塊的影響不大。
                在上面這個圖中,沒有列出來的一個很重的類,就是 Notification 類,這個類為什么十分重要,可以說也是PureMVC的潤滑劑,因為他是連接MVC各大部分的一個消息機制,就像是Cairngome里面的CairngomeEvent與FrontController,為了實現(xiàn)更好的松耦合,就是靠這個消息機制,因為各大部分中,很少直接的引用調(diào)用,而是以“發(fā)消息”(或者說是通知吧)來相互數(shù)據(jù)交流與通訊,這里是很好的使用了“觀察者模式”,因此,在某一部分改變的處理邏輯的話,只是它所發(fā)送的消息沒有改變,或者所偵聽的消息沒有改變,那么就不會影響到其它部分。
                另外要注意幾點,Command類是短生命周期的,也就是說,當有消息通知需要用到該Command進行處理時,F(xiàn)acade就會創(chuàng)建這個Command類,并將數(shù)據(jù)傳入Command里面進行處理,當處理完成后,其生命周期就會結(jié)束,所以不要將一些長生命周期的數(shù)據(jù)存放在Command里,比如不要將一些狀態(tài)數(shù)據(jù)信息存放在Command里面。還有就是Proxy類只會發(fā)送“消息”(通知),而不會接收任何消息,而Mediator與Command則可以發(fā)送與接收,所以你不能直接發(fā)消息通知Proxy去加載數(shù)據(jù),而是通過引用Proxy的實例調(diào)用相關(guān)的函數(shù)。理論就說了一大堆了,我們來看看那個MP3播放器實例吧!

          我們先來看看主程序的代碼,PureMVC的入口點:
           1 <?xml version="1.0" encoding="utf-8"?>
           2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
           3                 xmlns:view="com.jiangzone.flex.pureplayer.view.ui.*"
           4                 verticalGap="2"
           5                 layout="vertical" creationComplete="fadace.startup(this)"
           6                 backgroundColor="0x444444">
           7     <mx:Style>
           8         //這里的CSS代碼略去
           9     </mx:Style>
          10    
          11     <mx:Script>
          12         <![CDATA[
          13             import com.jiangzone.flex.pureplayer.ApplicationFacade;
          14            
          15             private var fadace:ApplicationFacade = ApplicationFacade.getInstance();
          16            
          17         ]]>
          18     </mx:Script>
          19     <mx:Box width="131">
          20         <view:ProgressBoard        id="progressBoard" />
          21         <view:ControlBoard         id="controlBoard" />
          22         <view:SongListBoard        id="songListBoard" />
          23     </mx:Box>
          24    
          25 </mx:Application>


          從上面代碼我們看到,定義了一個 facade 這個就是Facade的一個實例,而ApplicationFacade是繼承自Facade類的,這個就是PureMVC的整個架構(gòu)的控制管理類,因為Facade是一個單例,所以不能直接new 的,所以在ApplicationFacade里面定義了一個靜態(tài)方法來獲取它的實例。在程序的createComplete事實觸發(fā)的時候,我們就調(diào)用facade.startup(this)這個方法,意思就是啟動整個框架。
          這里的代碼都比較簡單,我們再來看看ApplicationFacade的代碼:

           1 package com.jiangzone.flex.pureplayer
           2 {
           3     import org.puremvc.as3.interfaces.IFacade;
           4     import org.puremvc.as3.patterns.facade.Facade;
           5     import org.puremvc.as3.patterns.observer.Notification;
           6    
           7     import com.jiangzone.flex.pureplayer.controller.StartupCommand;
           8    
           9     public class ApplicationFacade extends Facade implements IFacade
          10     {
          11         // Notification name constants
          12         public static const STARTUP:String             = "startup";
          13        
          14        
          15         /**
          16          * Singleton ApplicationFacade Factory Method
          17          */
          18         public static function getInstance() : ApplicationFacade {
          19             if ( instance == null ) instance = new ApplicationFacade( );
          20             return instance as ApplicationFacade;
          21         }
          22        
          23         /**
          24          * Start the application
          25          */
          26          public function startup(app:Object):void
          27          {
          28              sendNotification( STARTUP, app );   
          29          }
          30 
          31         /**
          32          * Register Commands with the Controller
          33          */
          34         override protected function initializeController( ) : void
          35         {
          36             super.initializeController();           
          37             registerCommand( STARTUP, StartupCommand );
          38         }
          39        
          40     }
          41 }


          這里分析一下,在ApplicationFacade類里,我們定義了一個String的常量,這個只是一個消息的類型,跟Flex里的Event的常量一樣的,注意,規(guī)范化一點的話,應該將消息類型的字符串都定義為常量,而我在后面的代碼中為了省事就直接用“XXXXX”這樣的字串代替了,還是建義寫成靜態(tài)常量。
          我們看到了startup()的代碼了,就是在剛才主程序里調(diào)用的那個函數(shù),這里接收了一個主程序的引用。
          我們還看到了有一個initializeController( ) 的函數(shù),當這個ApplicationFacade被實例化加載的時候,會先自動調(diào)用initializeController( ) 這個函數(shù),所以,我們應當在ApplicationFacade在被初始化的時候,就對Command進行注冊,說就是注冊,其實也只是將一個Command與一個消息綁定在一起而已。當發(fā)送該消息時,F(xiàn)acade就會自動的找到那個Command并實例化執(zhí)行。
          registerCommand( STARTUP, StartupCommand );這句就是對Command進行注冊的代碼,registerCommand都是父類或接口里面定義的方法,我們先不用管它,STARTUP就是上面定義的一個常量,表示一個消息的類型,StartupCommand這個類就是我定義的一個Command類,這里說白了就是STARTUP這個字符串常量就是一個Key,而StartupCommand就是一個Value,存放在一個數(shù)組里面,當有人發(fā)送一個STARTUP的消息時,程序就自動生成一個StartupCommand來處理。
          我們再看看startup()這個方法,在剛才的主程序里調(diào)用這個方法時,傳入了一個傳入了一個參數(shù)this,就是主程序本身,在startup()方法里面,發(fā)送了一個消息 sendNotification( STARTUP, app );    sendNotification()這個是發(fā)送消息的方法,第一個參數(shù)是消息的類型,第二個是可選參數(shù),是消息的內(nèi)容(消息體),在這里,將主程序的引用作為消息體綁在消息里一起發(fā)送了。由于之前在初始化的時候?qū)TARTUP消息類型與StartupCommand綁定在一起了,所以當發(fā)送這個消息的時候,StartupCommand將會被通知,所以這時候,程序的流程就跳入到StartupCommand類里面。下面我們來看StartupCommand類的內(nèi)容:

           1 package com.jiangzone.flex.pureplayer.controller
           2 {
           3     import org.puremvc.as3.interfaces.ICommand;
           4           //這里略去一些import代碼
           5     import com.jiangzone.flex.pureplayer.model.PlayListProxy;
           6    
           7     public class StartupCommand extends SimpleCommand implements ICommand
           8     {
           9         override public function execute( note:INotification ) : void   
          10         {
          11             /**
          12              * 獲取消息體內(nèi)容,在發(fā)送STARTUP消息時,將主程序PurePlayer作為消息體跟隨消息傳送
          13              */
          14             var app:PurePlayer = note.getBody() as PurePlayer;
          15            
          16             /**
          17              * 注冊代理(Model)
          18              */
          19             facade.registerProxy(new SongProxy());
          20             facade.registerProxy(new PlayListProxy());
          21             /**
          22              * 注冊ViewComponents或者UI組件的中介器。
          23              */
          24              facade.registerMediator(new ControlBoardMediator(app.controlBoard));
          25              facade.registerMediator( new SongListBoardMediator(app.songListBoard));
          26              facade.registerMediator(new ProgressBoardMediator(app.progressBoard));
          27              
          28              (facade.retrieveProxy(PlayListProxy.NAME) as PlayListProxy).loadPlayList();
          29         }
          30     }
          31 }


          上面的就是一個Command的代碼,注意,一個Command必需要實現(xiàn)ICommand接口,而如果是一個單Command的話,就需要繼承SimpleCommand類,而如果是一個Command鏈的話,就需要實現(xiàn)MacroCommand,至于Command鏈,如果有J2EE基礎的話,也就是Filter的過濾器鏈差不多。這里不多說。大家可以看看PureMVC的官方文檔與API!
          在Command里,都需要覆蓋execute 這個方法,這個方法就是執(zhí)行你的邏輯代碼的地方,由Facade自動調(diào)用,當這個Command所綁定的消息被發(fā)送時,F(xiàn)acade就會創(chuàng)建一個Command實例并調(diào)用execute方法,方法里還傳入一個INotification參數(shù),就是你所發(fā)送的那個消息,里面包含了消息類型名稱與消息體。在這個Command里,我沒有處理什么,因為這個Command用于啟動程序框架的,所以只在這里初始化了一些程序需要用到的資源,如注冊代理與注冊中介器,我們可以看到,注冊代理與注冊中介器的方法與注冊Command的方法不同,注冊Command的話,需要一個消息名稱與一個Command類綁定,而代理與中介器的注冊就不需要與消息綁定,直接將代理與中介器實例化之后進行注冊就可以了。這是由于Command的生產(chǎn)控制不是由用戶來操作的,是由Facade里面的一個工廠方法來對Command實例化并管理的,所以需要與一個消息名稱進行綁定,而代理與中介器就是用戶管理的,通常一個代理就對應一個數(shù)據(jù)結(jié)構(gòu),如果有幾個數(shù)據(jù)結(jié)構(gòu)都比較簡單,就可以在一個Proxy里管理,而同理,中介器也一樣,一個中介器對一個Flex組件,但為一個Button建立一個中介器未名太浪費了,所以我這里都是將MP3分成三個部分,控制按鈕部分,歌曲列表部分,播放進度部分,三個部分用三個中介器。通常這些中介器或者Proxy創(chuàng)建一次就可以了,F(xiàn)acade會將它它存放在數(shù)組中,當需要用到時,再由Facade來獲取他們,所以,在注冊代理與中介的時候,先實例化它們再注冊!因為Command是短生命周期,而Proxy與Mediator是長生命周期,所以這里與Command有點區(qū)別。在實例化中介器的時候,我傳入一個app.controlBoard的值:
          new ControlBoardMediator(app.controlBoard),就是說,我這個中介器是對應app.controlBoard這個控件,app就是主程序。
          當所有需要的資源都注冊好后,我執(zhí)行了下面一句代碼:
           (facade.retrieveProxy(PlayListProxy.NAME) as PlayListProxy).loadPlayList();
          之前講到,注冊代理時,將代理的實例進行注冊,實際上就只是在Facade里將這個代理實例放進數(shù)組里而已,所以用facade.retrieveProxy()這個方法可以再次獲得那個實例的引用,再調(diào)用這個代理里的一個方法loadPlayList()來進行加載播放列表。上上上面已經(jīng)說過,因為Proxy是只可以發(fā)信息,不可以收信息,所以你叫Proxy工作的話,只好得到它的引用再調(diào)用它的方法來控件它的工作。注意,在Facade重新獲得代理的方法里facade.retrieveProxy(PlayListProxy.NAME) as PlayListProxy  你需要指定一個字符串來獲取某一個代理,在編寫每一個代理時,都要為它指定一個name的字符串,而且是代理的唯一標識!這個時候,程序的流程就會跳到代理里運行l(wèi)oadPlayList()這個方法。下面,我們來看看PlayListProxy的代碼:

           1 package com.jiangzone.flex.pureplayer.model
           2 {
           3     import org.puremvc.as3.interfaces.IProxy;
           4           //省略import代碼
           5     import flash.xml.XMLNode;
           6 
           7     public class PlayListProxy extends Proxy implements IProxy
           8     {
           9         //定義一個代理的名字,唯一的標識
          10         public static const NAME:String = 'PlayListProxy';
          11         //定義一個HttpService,用于獲取遠程的數(shù)據(jù)
          12         private var hs:HTTPService;
          13        
          14         public function PlayListProxy():void{
          15             super(NAME,new Array());
          16             hs = new HTTPService();
          17             hs.addEventListener(ResultEvent.RESULT,onResult);
          18             hs.addEventListener(FaultEvent.FAULT,onFault);
          19         }
          20        
          21         public function get playList():Array{
          22             return data as Array;
          23         }
          24        
          25         public function loadPlayList(url:String = 'jiang/pureplayer/data/playlist.xml'):void{
          26             hs.method = "GET";
          27             hs.resultFormat = "xml";
          28             hs.url = url + '?ranid=' + (new Date()).time;
          29             hs.send();
          30         }
          31        
          32         private function onFault(e:FaultEvent):void{
          33 
          34         }
          35        
          36         private function onResult(e:ResultEvent):void{
          37             var arr:Array = data as Array;
          38             var xmlNode:XMLNode = e.result as XMLNode;
          39             for(var i:String in xmlNode.childNodes){
          40                 var obj:Object = new Object();
          41                 var node:XMLNode = xmlNode.childNodes[i];
          42                 obj["label"= node.attributes.label;
          43                 obj["data"= node.attributes.data;
          44                 arr.push(obj);
          45             }
          46             sendNotification("GET_PLAYLIST_COMPLETE",data);
          47         }
          48     }
          49 }


          很累呀。。。休息一會,抽根煙繼續(xù)!

          來分析一下代碼,在該代理被實例化時,會調(diào)用super(NAME,new Array());這個父類的方法,其實Proxy的構(gòu)造函數(shù)接收兩個參數(shù),一個是Proxy的唯一標識名字,另一個就是所需要作代理的數(shù)據(jù),是一個Object,就是說,你的這個Proxy類要對哪些數(shù)據(jù)作代理呢?就是這個值傳入的,在Proxy基類里面有一個data的屬性,這個屬性就是存放你的實際數(shù)據(jù),所以在我的這個PlayListProxy構(gòu)造時,我創(chuàng)建了一個Array來作為我的數(shù)據(jù),因為我這個代理,是代理一個播放列表數(shù)據(jù)的,所以我將用Array來存放我的播放列表數(shù)據(jù)。所以就將new Array()的值交給父類構(gòu)造器里,父類構(gòu)造器將會對該Array存放在data這個變量屬性里。由于data是Object類型的,所以我們獲取這個data的時候,還要對其轉(zhuǎn)換成相應的類型,所以為了方便,我寫了一個getter方法來封裝這個操作:
          1 public function get playList():Array{
          2     return data as Array;
          3 }

          以后可以直接調(diào)用playList屬性來獲取Array類型的數(shù)據(jù)了。
          而在 loadPlayList 這個函數(shù)里,接收一個可選參數(shù)url,通過HttpService來獲取該url中的xml數(shù)據(jù)。
          按照上上上上上面說的那樣,Proxy只有一個,但你可以按不同用途分為Local Proxy,與Remote Proxy,而這里它的作用就是Remote Proxy,因為他是操作遠程數(shù)據(jù)。
          當接收數(shù)據(jù)成功時,調(diào)用了 onResult 方法,里面進行了XML簡單的分析,其實可以將該分析操作交給一個Command來完成,但是這里確實是太簡單的分析了,就沒有必交給Command了,自已來完成吧。當解析完成時,發(fā)送了一個消息sendNotification("GET_PLAYLIST_COMPLETE",data);
          這里要說明一下,這里用了發(fā)消息來通知其它模塊說我已獲得數(shù)據(jù)了,你們誰對這個數(shù)據(jù)有興趣就拿去吧。(本人覺得這樣理解更有趣并容易理解)由于是這個機制,所以無論你界面怎樣改變,中介器怎樣改變,都不會影響到我Proxy,因為我獲得數(shù)據(jù)時,我不用引用你某一個中介器(如果中介器改變了,則同時要修改Proxy的代碼),我只發(fā)送一個消息,你們要則要,不要則罷,所以你界面如何改變的話,只要接收這個消息就可以同樣的得到了數(shù)據(jù),而不用因界面的修改而修改Proxy。這樣就可以將Mediator與Proxy松耦了。
          至于,是誰對這個“GET_PLAYLIST_COMPLETE”感興趣呢?我在上上上面說過,Proxy只會發(fā),不會收,所以肯定不是其它Proxy對這消息有興趣,而Command么,Command感興趣的消息都是在Facade里給綁定的,而我們上上上面的代碼中,F(xiàn)acade只綁定了STARTUP這個消息,所以現(xiàn)在唯一下來的,就是中介器了,因為中介器也是可以收與發(fā)消息的。如果一個中介器(或者說一個界面組件吧)對一個消息感興趣的話,那就需要在中介器的類里面定義這些感興趣的消息,下面我們來看看一個ControlBoardMediator的中介器的代碼:
           1 package com.jiangzone.flex.pureplayer.view
           2 {
           3     import org.puremvc.as3.patterns.mediator.Mediator;
           4     import org.puremvc.as3.interfaces.IMediator;
           5     import com.jiangzone.flex.pureplayer.view.ui.SongListBoard;
           6     import flash.events.MouseEvent;
           7     import mx.events.ListEvent;
           8     import org.puremvc.as3.interfaces.INotification;
           9     import mx.controls.List;
          10     import mx.collections.ArrayCollection;
          11 
          12     public class SongListBoardMediator extends Mediator implements IMediator
          13     {
          14         public static const NAME:String = "SongListBoardMediator";
          15        
          16         public function SongListBoardMediator(vc:Object):void{
          17             super(NAME,vc);
          18             songListBoard.songList.doubleClickEnabled = true;
          19            
          20             songListBoard.songList.addEventListener(ListEvent.ITEM_DOUBLE_CLICK,onDoubleClick);
          21         }
          22        
          23         public function get songListBoard():SongListBoard{
          24             return viewComponent as SongListBoard;
          25         }
          26        
          27         public function get songList():List{
          28             return songListBoard.songList;
          29         }
          30        
          31         private function onDoubleClick(e:ListEvent):void{
          32             var str:String = (e.target.selectedItem.data as String);
          33             sendNotification("GET_SONG_URL_COMPLETE",str);
          34         }
          35        
          36         override public function listNotificationInterests():Array{
          37             return [
          38                        "GET_SONG_URL",
          39                        "GET_PREV_URL",
          40                        "GET_NEXT_URL",
          41                        "GET_PLAYLIST_COMPLETE"
          42                    ];
          43         }
          44        
          45         override public function handleNotification(note:INotification):void{
          46             switch(note.getName()){
          47                 case "GET_SONG_URL":
          48                     if(songList.selectedItem)
          49 
          50 
          51                         sendNotification("GET_SONG_URL_COMPLETE",songList.selectedItem.data as String);
          52                     break;
          53                 case "GET_PREV_URL":
          54                     if(songList.selectedItem){
          55                         var i:int = songList.selectedIndex;
          56                         i -= 1;
          57                         if(i<0) i = (songList.dataProvider as ArrayCollection).length - 1;
          58                         songList.selectedIndex = i;
          59                         sendNotification("GET_PREV_URL_COMPLETE",songList.selectedItem.data as String);
          60                     }
          61                     break;
          62                 case "GET_NEXT_URL":
          63                     if(songList.selectedItem){
          64                         var i:int = songList.selectedIndex;
          65                         i = (i + 1% (songList.dataProvider as ArrayCollection).length;
          66                         songList.selectedIndex = i;
          67                         sendNotification("GET_PREV_URL_COMPLETE",songList.selectedItem.data as String);
          68                     }
          69                     break;
          70                 case "GET_PLAYLIST_COMPLETE":
          71                     var arr:Array = note.getBody() as Array;
          72                     songList.dataProvider = arr;
          73             }
          74         }
          75     }
          76 }


          在這份代碼中,我們主要看看幾個方法函數(shù),其它的都只是處理邏輯,控制Sound的播放什么的,與PureMVC關(guān)系不大了。我們主要看看這幾個方法:
          override public function listNotificationInterests():Array
          override public function handleNotification(note:INotification):void
          先說第一個方法,這個方法返回的是一個數(shù)組,我們上面說到,怎么知道中介器對哪些消息感興趣呢?就在這個方法里設置了,這些都是接口里的方法,所以需要override,在這個方法里,直接返回一個字符串數(shù)組就可以了,而那些字符串,就是你的消息名稱 的字符串,剛才Proxy中,處理完數(shù)據(jù)后,發(fā)了一個“GET_PLAYLIST_COMPLETE”的消息,并將處理好的數(shù)據(jù)作為消息體一起發(fā)送出去了。
          而在這個Mediator里的listNotificationInterests里,返回一個
          1 return [
          2     "GET_SONG_URL",
          3     "GET_PREV_URL",
          4     "GET_NEXT_URL",
          5     "GET_PLAYLIST_COMPLETE"
          6 ];

          看到?jīng)]有?那個數(shù)組里面包含了GET_PLAYLIST_COMPLETE這個消息名稱字符串。所以,當有人發(fā)送這個消息時,這個中介器就會進行響應,至于對這個消息的響應程序,就在
          override public function handleNotification(note:INotification):void
          這個方法里面寫上消息響應代碼。
          在響應函數(shù)里,都用switch(note.getName())來區(qū)分處理它所接收到的消息的名稱,再處以不同的處理代碼。

          好了,基本上,整個PureMVC的結(jié)構(gòu)就這樣了,流程是比較簡單,就是用消息(Notification)來圍繞MVC各個部分模塊來開發(fā)。這個程序還有其它的中介器類,代理類還有其它的類就不一一列出來了,反正PureMVC工作方式都是一樣的,只是對應的功能邏輯不一樣。

          呼,終于全部寫完了,下面給出整個Flex Project 的 源代碼:
          [down=http://www.jiangzone.com.cn/attachments/month_0806/t200864163352.zip]點擊下載此文件[/down]



          posted on 2008-07-29 14:44 姜大叔 閱讀(4992) 評論(32)  編輯  收藏 所屬分類: Flash/Flex

          評論:
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2008-08-10 11:27 |
          好崇拜哦!!
          樓主,源代碼下載不了哦,能發(fā)一份給我嗎?目前我很需要,拜托樓主!!!我的Email:cjc19762338@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-08-10 16:13 | sqw00453579
          好厲害啊``我也想學習```可以給個源代碼嗎```謝謝了```
          我的郵箱``sqw00453579@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-08-20 14:37 | HUIHUI
          的確厲害。 我想學 我也要個源碼 3Q~~~
          我的郵箱:huiqian1984@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-09-04 21:58 | zdcgh
          sysucgh#163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-09-16 10:07 | nova
          向你請教一個問題:用swfloader載入一個swf文件,當這個swf文件中有一個combbox的話,這個combox會有問題。具體就是,在第二次load這個文件的時候,里面的combox不能正常使用,不知道你遇到過嗎?不知你是否能給我指點。
          tieying-sky@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2008-10-28 10:52 |
          求一份源文件!!
          Email:wwj256@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2008-11-04 13:59 |
          求得一分源文件。~謝謝
          zhouyanjie@cdeledu.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-11-05 14:40 | CALM
          求一份源文件。~謝謝
          calm7@sohu.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-11-12 14:38 | 530705296@qq.com
          你好,源碼不能下載啊,是否網(wǎng)址有錯,發(fā)一份到我的郵箱530705296@qq.com好嗎?謝謝》  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-11-12 22:40 | 小亂
          求源文件
          yunaiming3@163.com
          萬分感激~~~~~~~~~~~~  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2008-12-02 16:48 | 副萊克斯
          恩,源碼不能下載 ,也給我發(fā)一份源碼吧 cjf868@163.com
          萬分感謝!!!  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2008-12-13 10:57 |
          樓主 真是大好人啊 你的這些講解讓我對PureMVC 有了進一步的了解

          感動  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-03-13 18:59 | ltdainiy
          源碼不能下載 ,也給我發(fā)一份源碼吧 ltdainiy@163.com
            回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-03-31 09:11 | anither
          源碼不能下載,樓主也給我發(fā)一份吧 anither@sohu.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-04-16 20:57 | 長沙滿哥
          zan yi ge  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-05-14 16:00 | ideadawn
          不知道博主還能看見我的回復不,看見的話也麻煩給我U一份吧,謝謝了,ideadawn@126.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-05-25 03:45 | wxz
          完整看了博主的這篇文章,還有有些疑惑,能否email一份源代碼給我,萬分感激!wxz859681117@yahoo.com.cn  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2009-07-12 12:34 | dave
          如果可以的話,也請樓主發(fā)一份完整代碼給我,謝謝
          davesong07@gmail.com
            回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-07-16 15:43 | pyd
          樓主都發(fā)了那么多份了,也發(fā)份給小弟我吧
          急需,麻煩您了
          pyd1053@163.com
          不勝感激啊。。。。。。。  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-07-23 11:06 | 王國金
          您好,樓主,你的源碼不能下載,請你發(fā)給我一份好嗎?
          king_wgj@hotmail.com
          謝謝你了!  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-10-22 13:43 | sdd
          不錯,給我一份,整學習中

          kevin51job@hotmail.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2009-11-01 14:22 | beyondpaul
          能給我一份源代碼嗎

          連接失效了··感謝 你


          25893458@qq.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2009-11-08 18:02 | 渴望
          給我一份吧,謝謝
          xyxc.105@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2010-04-02 10:36 | JAM
          講解得很精辟, 樓主一定把源碼看過了吧,要是能把框架的源碼結(jié)合進去說明下,想必條理能夠更清晰.   回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2010-07-21 15:49 | 我要源代碼
          求源代碼
          huangfang20065128@163.com
          感謝 你……  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2010-12-13 10:38 | iLinux
          代碼需求好踴躍  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2012-04-23 22:33 | 輕淌
          樓主都發(fā)了那么多份了,也發(fā)份給小弟我吧
          15891448250@163.com
          不勝感激啊。。。。。。。  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2012-05-09 14:35 | 王斌
          我只想說,樓主真犀利啊,樓主辛苦了哈  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2013-01-29 18:02 | hugangyong
          寫得還可以,但我補充幾點:mvc的好處和壞處,每個貼,每個人講的都大同小異,大家可以找?guī)讉€看看。但是從管理學和風險上來講,mvc框架做到了以人為本,因地制宜,何解,很多情況下開發(fā)團隊的人員的經(jīng)驗和特長不一,作為一個好的項目經(jīng)理,如果運用好這把利劍,那么,他們每個人將發(fā)揮自己的優(yōu)勢,鍛煉自己的信心,對人的發(fā)展最有利,其他的好處我不說了,我打個比方,一個剛從學校畢業(yè)的有熱情有求知欲但是目前能力不夠的人,如果從縱面上給他分配開發(fā)任務,這基本上是浪費了人才的同時增大了風險,最大的弊病是對人的發(fā)展極為不利,這樣的結(jié)果有三種,一:此人壓力過大,走人,二:此人沒有完成任務,三:此人在別人的幫助下勉強的完成了任務,但耗費了很多不必要的時間。上面幾種情況對人的成長和信心的是不小的毀滅。但是從橫向面上則不一樣,界面的樣式不需要很懂業(yè)務,并且可以很快的開發(fā)修改,并且有效果,即我們的v,時間有限,這里就不繼續(xù)講了  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析[未登錄] 2013-03-24 15:59 | hua
          求源碼啊樓主!
          hua14300@163.com  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2014-09-25 16:38 | rong
          有沒有源碼提供啊,多謝!!!  回復  更多評論
            
          # re: 基于PureMVC的一個Flex MP3播放器分析 2014-09-25 16:38 | rong
          272914287@qq.com
          能不能發(fā)份源碼到我郵箱啊,萬分感謝!!  回復  更多評論
            
          主站蜘蛛池模板: 湘潭市| 固镇县| 滁州市| 名山县| 昌图县| 岢岚县| 漳州市| 垫江县| 蓬溪县| 桂东县| 铜鼓县| 尚志市| 集贤县| 历史| 佛山市| 禹城市| 兰西县| 红河县| 开鲁县| 宜宾市| 达日县| 凤山县| 汉沽区| 友谊县| 五指山市| 高清| 正镶白旗| 枣庄市| 遂平县| 涟源市| 八宿县| 曲靖市| 乐至县| 洪雅县| 铜川市| 团风县| 新津县| 襄樊市| 永春县| 浦城县| 崇信县|