「PureMVCサンプル解説2」の編集履歴(バックアップ)一覧はこちら
「PureMVCサンプル解説2」(2008/08/20 (水) 11:51:29) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
さて、次はいよいよPureMVCの1.Controllerの解説に移りましょう。
PureMVCではController層に位置するクラスは以下の2つです。
・ Facadeクラス
・ Commandクラス
この点については前述していますね。
ですので概要についてはそちらにお任せして、実際のプログラムを見てみましょう。
まずはPureMVCのもっとも重要なクラスであるfacadeクラスです。
「ApplicationFacade.as」
package example
{
import org.puremvc.interfaces.IProxy;
import org.puremvc.patterns.facade.Facade;
import org.puremvc.interfaces.INotification;
import org.puremvc.interfaces.IFacade;
import org.puremvc.interfaces.IMediator;
import example.controller.*;
/**
* アプリケーションの根幹の振る舞いを書くところ
*/
public class ApplicationFacade extends Facade implements IFacade ・・・・・・・・・・・・・・・・・・・・・①
{
public static const APP_START_UP:String = "appStartUp"; ・・・・・・・・・・・・・・・・・・・②
public static const APP_NUMBER_CLICK:String = "appNumberButtonClick";
public static const APP_PLUS_CLICK:String = "appPlusButtonClick";
public static const APP_MINUS_CLICK:String = "appMinusButtonClick";
public static const APP_EQUAL_CLICK:String = "appEqualButtonClick";
public static const APP_CLEAR_CLICK:String = "appClearButtonClick";
/**
* インスタンスを取得するメソッド
* @return ApplicationFacade
*/
public static function getInstance():ApplicationFacade ・・・・・・・・・・・・・・・・・・・・・③
{
// 静的インスタンスの判定
if( instance == null )
{
// インスタンスが生成されていなければインスタンス化
instance = new ApplicationFacade(); ・・・・・・・・・・・・・・・・・・・・・④
}
return instance as ApplicationFacade; ・・・・・・・・・・・・・・・・・・・・・⑤
}
/**
* Facadeクラスの初期化
* ここでは最初に実行されるコマンドを登録する
*/
override protected function initializeController():void ・・・・・・・・・・・・・・・・・・・・⑥
{
// 親クラスの初期化
super.initializeController(); ・・・・・・・・・・・・・・・・・・・・・⑦
// AppStartUpCommandというクラスをAPP_START_UPというイベントと関連付け
registerCommand(APP_START_UP,AppStartUpCommand); ・・・・・・・・・・・・・・・・・・・・・⑧
}
}
}
① public class ApplicationFacade extends Façade implements IFacade
Facadeクラスの宣言部。
ここではFacadeクラスの継承とIFacadeインターフェースの実装を宣言しています。
IFacadeインターフェースはその名の通り、インターフェースを提供しているだけであり、
処理実態としてはFacadeクラスのほうでしょう。
このFacadeクラスがイベントの登録がそのハンドラの実行を束ねているといえるでしょう。
② public static const APP_START_UP
ここではアプリケーション全体のイベントをピックアップしています。
PureMVCの考え方ではイベント(またはそれをハンドルするハンドラ)は各Viewコンポーネントが実装することになっています。
ではこのFacadeクラスで定義されたものは何か?
それはアプリケーション全体として、実行しなければならないイベントをここで定義しています。
今回では簡単な計算機を模して作っていますので、以下のようなイベントを用意しました。
・APP_START_UP・・・・・アプリケーションのスタートアップ(CreationComplete時実行イベント名)
・APP_NUMBER_CLICK・・・番号の0~9のボタンをクリックされたときのイベント名
・APP_PLUS_CLICK・・・・プラスボタンをクリックされたときのイベント名
・APP_MINUS_CLICK・・・マイナスボタンをクリックされたときのイベント名
・APP_EQUAL_CLICK・・・イコールボタンをクリックされたときのイベント名
・APP_CLEAR_CLICK・・・クリアボタンをクリックされたときのイベント名
③ public static function getInstance():ApplicationFacade
facadeクラスのインスタンスを取得するメソッドです。
facadeクラスはアプリケーションにつき、ひとつです。
よって、静的領域に管理する必要があります。
静的領域にインスタンスがなければここで静的領域にfacadeクラスのインスタンス化をして(④)、
そのオブジェクトを返却します。(⑤)
④ instance = new ApplicationFacade();
⑤ return instance as ApplicationFacade;
⑥ override protected function initializeController():void
Facadeクラスのメソッド「initializeController」メソッドをオーバーライドしています。
Façadeクラスのコンストラクタの中で呼び出されるメソッドで、
このメソッドでは主にCommandクラスとイベント名(を表した文字列)との関連付けを行います。
それが⑧です。
⑦ super.initializeController();
親クラスの同メソッドを実行します。
⑧ registerCommand(APP_START_UP,AppStartUpCommand);
このメソッドでAPP_START_UPという文字列のイベントに対してAppStartUpCommandというCommandクラスを
関連付けしています。
この関連付けにより、APP_START_UPという文字列のイベントが送出された場合はAppStartUpCommandが自動的に
呼び出されるようになるわけです。
では、次にCommandクラスを見てみましょう。
「AppStartUpCommand.as」
package example.controller
{
import org.puremvc.interfaces.ICommand;
import org.puremvc.patterns.command.SimpleCommand;
import org.puremvc.interfaces.INotification;
import example.model.CalclationProxy;
import example.view.components.CalclationPanel;
import example.view.CalclationPanelMediator;
/**
* アプリケーション初期起動時実行コマンドクラス
*/
public class AppStartUpCommand extends SimpleCommand implements ICommand ・・・・・・・・・・・・・・・・・・・・・・・①
{
/**
* 処理
*/
override public function execute(notification:INotification):void ・・・・・・・・・・・・・・・・・・・・・・・②
{
// Proxyクラスをfacadeクラスに登録(ちなみに「facade」は静的に確保されているのでここでいきなり登場する)
// Proxyクラスは実際にロジックを実装していくところで、そのインスタンスはfacadeクラスで一括管理される。
facade.registerProxy( new CalclationProxy() ); ・・・・・・・・・・・・・・・・・・・・・・・・③
// VIEWコンポーネントの取得
var app:PureMVC_Calclation = notification.getBody() as PureMVC_Calclation; ・・・・・・・・・・・・・・④
// VIEWコンポーネントと関連するMediatorクラスの登録
// Mediatorクラスは実際に画面へ値を表示するところを請け負うもの。
// Proxyクラスへの橋渡しはこのMediatorクラスで行う。
facade.registerMediator( new CalclationPanelMediator( app.calcPanel )); ・・・・・・・・・・・・・⑤
}
}
}
① public class AppStartUpCommand extends SimpleCommand implements ICommand
Commandクラスの宣言部。
ここではSimpleCommandクラスの継承とICommandの実装を行っています。
Commandクラスの役目はexecuteメソッドの実装にあります。
② override public function execute(notification:INotification):void
このクラスの肝ですね。
facadeクラスによって関連付けされたイベントはこのCommandクラスのexecuteメソッドを発行します。
よって、この中にはこのアプリケーションの中で使用されるであろうビジネスロジック実装をしたModel層のProxyクラスのインスタンス化と登録、
データバインドをしたView層のMediatorクラスのインスタンス化及びfaçadeへの登録を行っています。
③ façade.registerProxy( new CalclationProxy() );
このアプリケーションで利用するためのProxyクラスを登録しています。
このregisterProxyメソッドを発行してProxyのインスタンスを登録しないと、Proxyクラスのインスタンスは保持されず、
結果としてビジネスロジックが実行されませんので、必ずこのメソッドを呼んでProxyクラスを登録しましょう。
今回は計算機能を用いているので、足し算、引き算、イコールの処理などを実装しているProxyクラス「CalclationProxy」の
インスタンスをここで登録しています。
ProxyクラスについてはModel層のサンプルのクラスを見ていくときにお話をしましょう。
④ var app:PureMVC_Calclation = notification.getBody() as PureMVC_Calclation;
親クラスであるMXMLのクラスを取得しています。
ここでMXMLのクラスを呼び出しているのは次の処理(⑤)でView層のクラスであるMediatorクラスに、
どのViewコンポーネントがインスタンス化されるMediatorクラスに必要なのかを設定するためです。
⑤ façade.registerMediator( new CalclationPanelMediator( app.calcPanel ));
親クラスであるPureMVC_Calclationの配下のcalcPanelは前述のMXMLファイルの中の<view:CalclationPanel>タグのidプロパティで
指定したインスタンス名です。
ここでViewコンポーネントを指定することにより、View層のMediatorクラスは初めてCalclationPanelのためのView層ロジック
「CalclationPanelMediator」として機能するようになります。
この辺りの詳しいことはView層のサンプルのクラスのときにお話をしましょう。
Controller層はここまでです。
FlexのFrameworkのひとつであるCaringormとは随分と違うことがお分かりでしょうか?
CairngormではApplicationControllerにCommand、Eventが集中し、
またイベントごとにCommandクラス、Eventクラスが生成されてしまい、非常にわかりにくいものとなっていました。
PureMVCはその煩雑さを幾分でも解消してくれるでしょう。
次はModelクラスの解説です。
さて、次はいよいよPureMVCの1.Controllerの解説に移りましょう。
PureMVCではController層に位置するクラスは以下の2つです。
・ Facadeクラス
・ Commandクラス
この点については前述していますね。
ですので概要についてはそちらにお任せして、実際のプログラムを見てみましょう。
まずはPureMVCのもっとも重要なクラスであるfacadeクラスです。
「ApplicationFacade.as」
package example
{
import org.puremvc.interfaces.IProxy;
import org.puremvc.patterns.facade.Facade;
import org.puremvc.interfaces.INotification;
import org.puremvc.interfaces.IFacade;
import org.puremvc.interfaces.IMediator;
import example.controller.*;
/**
* アプリケーションの根幹の振る舞いを書くところ
*/
public class ApplicationFacade extends Facade implements IFacade ・・・・・・・・・・・・・・・・・・・・・①
{
public static const APP_START_UP:String = "appStartUp"; ・・・・・・・・・・・・・・・・・・・②
public static const APP_NUMBER_CLICK:String = "appNumberButtonClick";
public static const APP_PLUS_CLICK:String = "appPlusButtonClick";
public static const APP_MINUS_CLICK:String = "appMinusButtonClick";
public static const APP_EQUAL_CLICK:String = "appEqualButtonClick";
public static const APP_CLEAR_CLICK:String = "appClearButtonClick";
/**
* インスタンスを取得するメソッド
* @return ApplicationFacade
*/
public static function getInstance():ApplicationFacade ・・・・・・・・・・・・・・・・・・・・・③
{
// 静的インスタンスの判定
if( instance == null )
{
// インスタンスが生成されていなければインスタンス化
instance = new ApplicationFacade(); ・・・・・・・・・・・・・・・・・・・・・④
}
return instance as ApplicationFacade; ・・・・・・・・・・・・・・・・・・・・・⑤
}
/**
* Facadeクラスの初期化
* ここでは最初に実行されるコマンドを登録する
*/
override protected function initializeController():void ・・・・・・・・・・・・・・・・・・・・⑥
{
// 親クラスの初期化
super.initializeController(); ・・・・・・・・・・・・・・・・・・・・・⑦
// AppStartUpCommandというクラスをAPP_START_UPというイベントと関連付け
registerCommand(APP_START_UP,AppStartUpCommand); ・・・・・・・・・・・・・・・・・・・・・⑧
}
}
}
① public class ApplicationFacade extends Façade implements IFacade
Facadeクラスの宣言部。
ここではFacadeクラスの継承とIFacadeインターフェースの実装を宣言しています。
IFacadeインターフェースはその名の通り、インターフェースを提供しているだけであり、
処理実態としてはFacadeクラスのほうでしょう。
このFacadeクラスがイベントの登録がそのハンドラの実行を束ねているといえるでしょう。
② public static const APP_START_UP
ここではアプリケーション全体のイベントをピックアップしています。
PureMVCの考え方ではイベント(またはそれをハンドルするハンドラ)は各Viewコンポーネントが実装することになっています。
ではこのFacadeクラスで定義されたものは何か?
それはアプリケーション全体として、実行しなければならないイベントをここで定義しています。
今回では簡単な計算機を模して作っていますので、以下のようなイベントを用意しました。
・APP_START_UP・・・・・アプリケーションのスタートアップ(CreationComplete時実行イベント名)
・APP_NUMBER_CLICK・・・番号の0~9のボタンをクリックされたときのイベント名
・APP_PLUS_CLICK・・・・プラスボタンをクリックされたときのイベント名
・APP_MINUS_CLICK・・・マイナスボタンをクリックされたときのイベント名
・APP_EQUAL_CLICK・・・イコールボタンをクリックされたときのイベント名
・APP_CLEAR_CLICK・・・クリアボタンをクリックされたときのイベント名
③ public static function getInstance():ApplicationFacade
facadeクラスのインスタンスを取得するメソッドです。
facadeクラスはアプリケーションにつき、ひとつです。
よって、静的領域に管理する必要があります。
静的領域にインスタンスがなければここで静的領域にfacadeクラスのインスタンス化をして(④)、
そのオブジェクトを返却します。(⑤)
④ instance = new ApplicationFacade();
⑤ return instance as ApplicationFacade;
⑥ override protected function initializeController():void
Facadeクラスのメソッド「initializeController」メソッドをオーバーライドしています。
Façadeクラスのコンストラクタの中で呼び出されるメソッドで、
このメソッドでは主にCommandクラスとイベント名(を表した文字列)との関連付けを行います。
それが⑧です。
⑦ super.initializeController();
親クラスの同メソッドを実行します。
⑧ registerCommand(APP_START_UP,AppStartUpCommand);
このメソッドでAPP_START_UPという文字列のイベントに対してAppStartUpCommandというCommandクラスを
関連付けしています。
この関連付けにより、APP_START_UPという文字列のイベントが送出された場合はAppStartUpCommandが自動的に
呼び出されるようになるわけです。
では、次にCommandクラスを見てみましょう。
「AppStartUpCommand.as」
package example.controller
{
import org.puremvc.interfaces.ICommand;
import org.puremvc.patterns.command.SimpleCommand;
import org.puremvc.interfaces.INotification;
import example.model.CalclationProxy;
import example.view.components.CalclationPanel;
import example.view.CalclationPanelMediator;
/**
* アプリケーション初期起動時実行コマンドクラス
*/
public class AppStartUpCommand extends SimpleCommand implements ICommand ・・・・・・・・・・・・・・・・・・・・・・・①
{
/**
* 処理
*/
override public function execute(notification:INotification):void ・・・・・・・・・・・・・・・・・・・・・・・②
{
// Proxyクラスをfacadeクラスに登録(ちなみに「facade」は静的に確保されているのでここでいきなり登場する)
// Proxyクラスは実際にロジックを実装していくところで、そのインスタンスはfacadeクラスで一括管理される。
facade.registerProxy( new CalclationProxy() ); ・・・・・・・・・・・・・・・・・・・・・・・・③
// VIEWコンポーネントの取得
var app:PureMVC_Calclation = notification.getBody() as PureMVC_Calclation; ・・・・・・・・・・・・・・④
// VIEWコンポーネントと関連するMediatorクラスの登録
// Mediatorクラスは実際に画面へ値を表示するところを請け負うもの。
// Proxyクラスへの橋渡しはこのMediatorクラスで行う。
facade.registerMediator( new CalclationPanelMediator( app.calcPanel )); ・・・・・・・・・・・・・⑤
}
}
}
① public class AppStartUpCommand extends SimpleCommand implements ICommand
Commandクラスの宣言部。
ここではSimpleCommandクラスの継承とICommandの実装を行っています。
Commandクラスの役目はexecuteメソッドの実装にあります。
② override public function execute(notification:INotification):void
このクラスの肝ですね。
facadeクラスによって関連付けされたイベントはこのCommandクラスのexecuteメソッドを発行します。
よって、この中にはこのアプリケーションの中で使用されるであろうビジネスロジック実装をしたModel層のProxyクラスのインスタンス化と登録、
データバインドをしたView層のMediatorクラスのインスタンス化及びfaçadeへの登録を行っています。
③ façade.registerProxy( new CalclationProxy() );
このアプリケーションで利用するためのProxyクラスを登録しています。
このregisterProxyメソッドを発行してProxyのインスタンスを登録しないと、Proxyクラスのインスタンスは保持されず、
結果としてビジネスロジックが実行されませんので、必ずこのメソッドを呼んでProxyクラスを登録しましょう。
今回は計算機能を用いているので、足し算、引き算、イコールの処理などを実装しているProxyクラス「CalclationProxy」の
インスタンスをここで登録しています。
ProxyクラスについてはModel層のサンプルのクラスを見ていくときにお話をしましょう。
④ var app:PureMVC_Calclation = notification.getBody() as PureMVC_Calclation;
親クラスであるMXMLのクラスを取得しています。
ここでMXMLのクラスを呼び出しているのは次の処理(⑤)でView層のクラスであるMediatorクラスに、
どのViewコンポーネントがインスタンス化されるMediatorクラスに必要なのかを設定するためです。
⑤ façade.registerMediator( new CalclationPanelMediator( app.calcPanel ));
親クラスであるPureMVC_Calclationの配下のcalcPanelは前述のMXMLファイルの中の<view:CalclationPanel>タグのidプロパティで
指定したインスタンス名です。
ここでViewコンポーネントを指定することにより、View層のMediatorクラスは初めてCalclationPanelのためのView層ロジック
「CalclationPanelMediator」として機能するようになります。
この辺りの詳しいことはView層のサンプルのクラスのときにお話をしましょう。
Controller層はここまでです。
FlexのFrameworkのひとつであるCaringormとは随分と違うことがお分かりでしょうか?
CairngormではApplicationControllerにCommand、Eventが集中し、
またイベントごとにCommandクラス、Eventクラスが生成されてしまい、非常にわかりにくいものとなっていました。
PureMVCはその煩雑さを幾分でも解消してくれるでしょう。
[[次はModelクラスの解説です。>http://www39.atwiki.jp/flex_framework/pages/20.html]]