Skip to main content

Robotlegs AS3 MVC framework in Flex project (I)

由於今天在 奶綠茶的 Robotlegs FlashAS3 MVC framework 看到他讚賞 Robotlegs AS3 MVC framework 的好用,不禁好奇的來研究一番...

其實這個 AS3 MVC framework 出現有些時日,但是一直都沒有特別的關注它。簡單看完 Robotlegs 最佳實踐,其實就可以大部分的了解 Robotlegs 運作的邏輯。不如其他的 MVC framework 有很多語言版本, Robotlegs 完全是專注在 AS3 上。也由於僅有一個版本,所以訊息傳遞是利用 AS3 Event 機制來完成,對於一些想要入門實作 MVC 的 Flash 工程師來說絕對是比 pureMVC 好入門很多...=)


Robotlegs 的重點就是搭著「 依賴注入( Dependency Injection) 」達成 MVCS 的架構,  擷取用最佳實踐的中文翻譯解釋:

Quote:
最簡單地, 依賴注入是為對象提供實例變量或屬性的行為. 當你傳遞一個變量到一個類的構造函數, 你在使用依賴注入. 當你設置一個類的屬性, 你在使用依賴注入. 如果你不是使用嚴格的過程或線性方式編寫AS3, 很可能你現在就在使用依賴注入。

呃...依賴注入? ?簡單來講一台霜淇林機,你要賣什麼口味的霜淇林就是依賴不同的原料放置到左右兩個攪拌桶內,而每一個口味可以透過介面實作來達成依賴注入。
以下是簡單的 Dependency Injection 的 Setter injection 範例:

public interface 霜淇淋介面
{
function 擠():void;
}

然後實作:

public class 巧克力 implements 霜淇淋介面{
public function 擠():void{
trace("巧克力口味的霜淇淋");
}
}
public class 草莓 implements 霜淇淋介面{
public function 擠():void{
trace("草莓口味的霜淇淋");
}
}
public class 香草 implements 霜淇淋介面{
public function 擠():void{
trace("香草口味的霜淇淋");
}
}

霜淇淋機台

public class 機台{
public var 左邊桶的霜淇淋:霜淇淋介面;
public var 右邊桶的霜淇淋:霜淇淋介面;

public function set左邊桶口味( obj:霜淇淋介面 ):void{
左邊桶的霜淇淋 = obj;
}
public function set右邊桶口味( obj:霜淇淋介面 ):void{
右邊桶的霜淇淋 = obj;
}
public function 擠綜合():void{
左邊桶的霜淇淋.擠();
右邊桶的霜淇淋.擠();
}
}

測試:

var 機台A:霜淇淋機台 = new 霜淇淋機台();
機台A.set左邊桶口味( new 巧克力 );
機台A.set右邊桶口味( new 香草 );
機台A.擠綜合(); // 香草巧克力~~

var 機台B:霜淇淋機台 = new 霜淇淋機台();
機台B.set左邊桶口味( new 草莓 );
機台B.set右邊桶口味( new 香草 );
機台B.擠綜合(); // 香草草莓


回到 Robotlegs 它用的是 轉接器 (adapter) 映射注入,就是將原料注入到一個反射庫轉接器 (SwiftSuspenders) 來用...反正就是一堆東西塞到核心反射庫轉接器內,程式用到時候自動幫你轉換取用...懶人最愛?

以下用一個很爛的範例來說明 Robotlegs 的 Injection 機制...
反正範例照貼就會出現下面的畫面~~

其實 Robotlegs 用法跟 pureMVC 很像,它也有使用 Command, Mediator, Proxy,但是又比 pureMVC 簡約很多...

先下載 最新版 Robotlegs
,解壓後 src 內的直接放到 Flex Project 的 src 下,SwiftSuspenders.swc 直接塞到 libs 下。

在 FlashBuilder 中開一個 Flex project names "RobotlegsInjectTest"

第一,做一個 MessageBox 的 mxml component 放到根目錄下:Robotlegs 的重點就是儘量不動你的 Flash/Flex class...

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var data:ArrayCollection;

private function init():void{
data = new ArrayCollection;
data.addItem("My instance name is "+ id );
}
public function update( newline:String ):void{
data.addItem( newline );
}
]]>
</fx:Script>
<s:List dataProvider="{data}" width="200" height="200" />
<s:Button label="Broadcasing" click="dispatchEvent(new Event('btnClick'))" />
</s:Group>


再來寫 MessageBox 用的 Mediator class:跟 pureMVC 一樣, viewComponent 歸 Mediator 操作

package
{
import flash.events.Event;
import org.robotlegs.mvcs.Mediator;

public class MessageBoxMediator extends Mediator
{
[Inject]
public var view:MessageBox;
//直接注入屬性,反正轉接器會自動幫你轉~~

public function MessageBoxMediator()
{
super();
}
override public function onRegister():void{
eventMap.mapListener( view , "btnClick" , onClick );
/*加入事件監聽的寫法
* 為什麼不實作 onRemove ? 機器腳體諒大家
* onPreRemove 就將一些 listener 都自動清乾淨了...懶人指數 + 1
*/這也是專攻一種語言的好處...=)
}
private function onClick(event:Event):void{
switch( event.type ){
case "btnClick":
view.update( "lalalala" );
break;
}
}
}
}


來做 Application 用的 Context...真的很類似 pureMVC 中的 Facade

package
{
import flash.display.DisplayObjectContainer;

import org.robotlegs.mvcs.Context;

public class TestRobotLegContext extends Context
{
public function TestRobotLegContext(contextView:DisplayObjectContainer, autoStartup:Boolean=true)
{
super(contextView, autoStartup);
}
override public function startup():void
{
//bootstrap here
// 預設自動化
//意思就是注入 mapping 後會自動幫你 on MessageBoxMediator...懶人指數 +1
mediatorMap.mapView( MessageBox, MessageBoxMediator );
}
}
}

最後在 RobotlegsInjectText.mxml 中寫上:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:views = "*"
minWidth="300" minHeight="300" creationComplete="new TestRobotLegContext(this)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label text="Robotlags framework demo 1" x="5" y="10" fontSize="16"/>
<views:MessageBox id="View1" y="40" x="10" />
</s:Application>

 

creationComplete="new TestRobotLegContext(this)"
//啟動 TestRobotLegContext


結束了~~~~~四個檔案就可以完成基本使用...也不怪乎一堆人對它的簡單入門推崇,懶人指數 X N!!!
以下有個很好的範例:
Shaun Smith 的 RobotLegs AS3: A DI Driven MVCS Framework for Flash & Flex – Inspired by PureMVC

後話:
因為目前並沒有實作過 Robotlegs 框架的中大型專案,所以沒辦法真正比較與 pureMVC 的優劣,但是看到目前為止, Robotlegs 對於想要入門實作 AS3 MVC framework 的不外乎是一個很好的選擇。尤其它與 pureMVC 有很多地方相似,對於想要學習 pureMVC 的朋友也可以是一個簡單入門的跳板。最後,想要 Flash 版的教學範例可以等奶綠茶老師的 Robotlegs 教學文章囉!

to be continue...=P

Comments

  1. 哇巫, 其實我貼就是想讓你看到, 我知道你一定會熱血, 嘿嘿, 這樣就有人可以一起討論

    ReplyDelete
  2. @milkmidi 哈哈哈哈被你陷害了,XD

    ReplyDelete
  3. 我在依賴注入的地方看很久看不太懂
    原來就是平常在用的介面==
    你解釋的真好
    謝謝你啦

    ReplyDelete
  4. RobotlegsInjectText.mxml裡的
    creationComplete="new HelloRobotLegContext(this)"
    寫錯了
    應該是
    creationComplete="new TestRobotLegContext(this)"
    才對

    ReplyDelete

Post a Comment

Popular posts from this blog

[AIR] JoSiResize - Mobile 開發小工具

JoSiResizev0.6.0,Adobe AIR 3 runtime之前開發 tool app 的時候並沒有很深刻的體認到圖片素材的 resize 是一個很麻煩的事情...畢竟圖片使用量並不大,等到開發遊戲類的 app 才發現光處理不同螢幕尺寸的圖片素材是一個相當折磨人的工作。
因此 JoSiResize app 誕生了~~~原理是採用最小 scale 長寬比例不變的方式進行放大縮小。使用方法非常簡單,設定好變更的尺寸,接下來,將需要處理的圖片檔案全選直接拖曳到視窗內,畫面即會跳出預備儲存的檔案夾選擇畫面,確認後即開始轉檔。

PureMVC for Titanium Mobile

為了秉持著哪裡都要用 PureMVC 的想法,試著修改 PureMVC 官網上提供的 Javascript 版本給 Titanium 使用。
**source code**
有任何問題請上:Titanium Mobile 中文開發者論壇

建立 instance 的方法:使用 Puremvc 為 namespace
Ti.include('puremvc-js-1.0.js');
var c = Puremvc.clone( Puremvc.SimpleCommand );
var p = Puremvc.clone( Puremvc.Proxy, "TestProxy", "This is TestProxy's data" );
var m = Puremvc.clone( Puremvc.Mediator , "MainMediator" );

[Unity] erinylin.lazylib - Cookie for PlayerPrefs

有鑑於 PlayerPrefs 測試與版本更新問題,將大家都愛用的 PreviewLabs.PlayerPrefs 打包起來,製作重點還是以懶人為主,基本上 PlayerPrefs 資料更新與數量並不可能會有強烈衝擊效能的狀況產生,所以為了方便開發,就弄了一個視覺化工具,方便除錯用。

雖然 PreviewLabs.PlayerPrefs 作者都宣告放棄他們的版權,不過為了尊重程式,僅僅加入了兩個公用函式,其他並無更改。

內有:
Cookie ManagerCookie 用 DataObject 混合編輯 ScriptableObject執行階段除錯視窗工具當然還是有懶人常數檔案輸出資料版本控制,方便更新版後儲存資料更新功能其實很多,有興趣的請自行到 Github 下載並參考範例吧!