Micro Architecture ─ PureMVC Part2

把之前的補完,先介紹一下Mediator

Mediator用來管理可見元件,讓原本UI能與PureMVC溝通,主要負責觸發跟反應Notification

ApplicationMediator


package idv.gd.pureMVCTest.view
{
import flash.events.MouseEvent;

import idv.gd.pureMVCTest.ApplicationFacade;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.mediator.Mediator;

public class ApplicationMediator extends Mediator
{
public static const NAME:String = "ApplicationMediator";

public function ApplicationMediator(viewComponent:Main)
{
super(NAME, viewComponent);
}

/**
* view內所有的元件註冊在此
*/
override public function onRegister():void
{
super.onRegister();

facade.registerMediator(new RSSReaderMediator(main.reader));

main.newsBtn.addEventListener(MouseEvent.CLICK, getNewsHandler);
main.techBtn.addEventListener(MouseEvent.CLICK, getTechHandler);
}

private function getNewsHandler(event:MouseEvent):void
{
facade.sendNotification(ApplicationFacade.READ_NEWS);
}

private function getTechHandler(event:MouseEvent):void
{
facade.sendNotification(ApplicationFacade.READ_TECH);
}

protected function get main():Main
{
return viewComponent as Main;
}
}
}

Mediator會對應到一個名稱,寫法上以常數宣告,讓Facade可取用對象,若Mediator所管理的UI有子元件,每個子元件都可在此註冊,在寫法上為了避免管理的子元件尚未生成,註冊元件時應盡量寫在onRegister裡,Constructor有時會出現問題

雖然Mediator可取得Proxy跟其它的Mediator,但會耦合性會過高,以Notification通知Command,再以Command操作Proxy的方式比較妥當,而Mediator去操作其它的Mediator是絕對不允許的

Proxy同Mediator要有一個識別名,用來管理資料及封裝操作的方法,實現Domain Logic,在官方文件還有一種RemoteProxy,不過我個人比較喜歡拆成Delegate跟Proxy,讓Delegate管遠端要值的方法,方便之後抽換

RSSProxy


package idv.gd.pureMVCTest.model
{
import idv.gd.pureMVCTest.ApplicationFacade;
import idv.gd.pureMVCTest.model.business.RSSDelegate;
import idv.gd.pureMVCTest.model.vo.InfoVO;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.rpc.IResponder;

import org.puremvc.as3.patterns.proxy.Proxy;

/**
* proxy用來維護資料,保有原始資料及操作方法
*/
public class RSSProxy extends Proxy implements IResponder
{
public static const NAME:String = "DataProxy";

public function RSSProxy(data:Object = null)
{
super(NAME, data);
}

/**
* 使用 delegate來取得內容,使用 delegate才方便抽換取得來源
*/
public function getRealNews():void
{
var delegate:RSSDelegate = new RSSDelegate(this);

delegate.getNews();
}

public function getTech3c():void
{
var delegate:RSSDelegate = new RSSDelegate(this);

delegate.getTech3c();
}

public function removeItemAt(index:uint):void
{
if (infoVO)
{
infoVO.content.removeItemAt(index);
}
}

public function removeAll():void
{
infoVO.content.removeAll();
}

public function result(resultEvent:Object):void
{
var data:Object = resultEvent.result;
var title:String = data.rss.channel.title;
var lastBuildDate:String = data.rss.channel.lastBuildDate;
var content:ArrayCollection = data.rss.channel.item;

var vo:InfoVO = new InfoVO(title, lastBuildDate, content);

this.data = vo;

this.facade.sendNotification(ApplicationFacade.RSS_LOAD_COMPLETE, infoVO);
}

public function fault(data:Object):void
{
this.facade.sendNotification(ApplicationFacade.RSS_LOAD_FAULT);
}

protected function get infoVO():InfoVO
{
return data as InfoVO;
}

}
}

在多核心的版本,其實只是多了一組管理Facade的Map,跟Mediator及Proxy一樣,生成時要有個識別的名字,其它用法一樣

Main.mxml



//進入點要有識別名,用來識別 facade instance
public const NAME:String = "Main";
private var facade:ApplicationFacade = ApplicationFacade.getInstance(NAME);

ApplicationFacade



public function ApplicationFacade (key:String)
{
super(key);
}

原始檔下載(Flex專案檔,附PureMVC Standard)

0 意見 :: Micro Architecture ─ PureMVC Part2