sonicjam的官方網站,兩個有趣的角色在唱歌,對話十分搞笑,網站由3D呈現,效果不錯
Flex 4 Gumbo
官方網站目前己可下載Milestone的SDK,雖然沒有IDE可用,但還是可體驗一下Flex4 Gumbo的新語法,比較特殊的是FXG跟State吧,其它的還在看
SDK下載頁面:http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4
官方介紹頁:http://opensource.adobe.com/wiki/display/flexsdk/Gumbo
[PureMVC] 使用Pipes Util 實現Module間溝通
之前在Micro Architecture PureMVC一篇有介紹到多核版的PureMVC架構,所謂的多核,指的是同一專案能出現多個實做PureMVC的模塊,在Flex是以Module的方式實現,讓每個Module都有各自的Facade,功能獨立。但PureMVC本身未提供Module間彼此溝通的方法,雖然我們可以用Interface等方法來管理每個Module,但這會使程式的關聯太高,失去MVC的好處,所幸己有高手解決了這個問題,官方網站的Pipes Util就是用來處理Module的問題,他能在Module間再架一層溝通架構,能每個Module都能像送Notification的方式彼此溝通,下面寫個簡單的範例說明
程式為Shell跟Module互傳訊息,Shell是讀入Module的主程式,Module是獨立的PureMVC架構
PipeUtil主要是靠JunctionMediator跟其它Module溝通,由於JunctionMediator是繼承自Mediator,所以可再收發Notification,使Module間的訊息可走回原本的PureMVC架構
package idv.gd.hellopipes.shell.view
{
import idv.gd.hellopipes.common.PipeAwareModule;
import idv.gd.hellopipes.shell.ApplicationFacade;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeAware;
import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeMessage;
import org.puremvc.as3.multicore.utilities.pipes.messages.Message;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.Junction;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.JunctionMediator;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.Pipe;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.TeeMerge;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.TeeSplit;
/**
* junction是實際拿來連結的實體,架構在原本的puremvc內(mediator)
*/
public class ShellJunctionMediator extends JunctionMediator
{
public static const NAME:String = "AppJunctionMediator";
public function ShellJunctionMediator()
{
//Junction為不可見的連結實體,用來管理 shell跟module的關係
super(NAME, new Junction());
}
override public function listNotificationInterests():Array
{
return [ApplicationFacade.MODULE_ADDED, ApplicationFacade.SEND_MESSAGE];
}
override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
case ApplicationFacade.MODULE_ADDED:
{
var module:IPipeAware = IPipeAware(note.getBody());
connectPipe(module);
break;
}
case ApplicationFacade.SEND_MESSAGE:
{
var message:Message = new Message(PipeAwareModule.SHELL_MESSAGE, null, note.getBody());
junction.sendMessage(PipeAwareModule.SHELL_TO_MODULE, message);
break;
}
}
}
/**
* 連結pipe跟接口
*/
private function connectPipe(module:IPipeAware):void
{
//註冊pipe及產生接口
junction.registerPipe(PipeAwareModule.SHELL_TO_MODULE, Junction.OUTPUT, new TeeSplit());
junction.registerPipe(PipeAwareModule.MODULE_TO_SHELL, Junction.INPUT, new TeeMerge());
//監聽訊息
junction.addPipeListener(PipeAwareModule.MODULE_TO_SHELL, this, handlePipeMessage);
//連結 module跟shell
var moduleToShell:Pipe = new Pipe();
module.acceptOutputPipe(PipeAwareModule.MODULE_TO_SHELL, moduleToShell);
var shellInFitting:TeeMerge = junction.retrievePipe(PipeAwareModule.MODULE_TO_SHELL) as TeeMerge;
shellInFitting.connectInput(moduleToShell);
//連結shell跟module
var shellToModule:Pipe = new Pipe();
module.acceptInputPipe(PipeAwareModule.SHELL_TO_MODULE, shellToModule);
var shellOutFitting:TeeSplit = junction.retrievePipe(PipeAwareModule.SHELL_TO_MODULE) as TeeSplit;
shellOutFitting.connect(shellToModule);
trace("connected");
}
override public function handlePipeMessage(message:IPipeMessage):void
{
switch (message.getType())
{
case PipeAwareModule.MODULE_MESSAGE:
{
sendNotification(ApplicationFacade.GET_MESSAGE, message.getBody());
break;
}
}
}
}
}
連結是透過Pipe監聽訊息,這部分寫起來比較麻煩,但可限制那些Module之間可以溝通,以及要監聽的訊息
Micro Architecture ─ PureMVC Part2
把之前的補完,先介紹一下Mediator
Mediator用來管理可見元件,讓原本UI能與PureMVC溝通,主要負責觸發跟反應Notification
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)
iPhone os 3.0 即將登場,仍不支援Flash
今天看到iPhone OS 3.0的新聞,雖然增加了許多功能,但最關心的Flash還是不支援 (="=),Adobe從去年10月就說Flash Player要登上iPhone,但至今仍無消息,我相信Adobe一定能解決Flash在iPhone上執行的問題,畢竟iPhone都可以放youTube了,剩下只看Apple肯不肯點頭
新聞頁面 http://www.techcrunch.com/2009/03/17/live-from-apples-iphone-30-press-conference/