PureMVC、というよりはすべてのロジックの肝となる
Model層について記述していきます。
この層で利用されるクラスは以下の通りです。
・
Proxyクラス
・
ValueObjectクラス
このクラスについても既に概要は述べています。
ので、ここではサンプルをあげてみていきましょう。
まずはProxyクラスです。
「CalclationProxy.as」
package
example.model
{
import
org.puremvc.interfaces.IProxy;
import
org.puremvc.patterns.proxy.Proxy;
import
mx.collections.ArrayCollection;
/**
* Proxyクラス
* 実際の処理の実態をここで記述する
*/
public class
CalclationProxy extends Proxy implements IProxy ・・・・・・・・・・・・・・・・・・・・@
{
// このクラスのNAMEプロパティの設定。このNAMEでfacade内のインスタンスは管理されるので、
// これはプロジェクトでユニークになること
public static const
NAME:String = "CalclationProxy"; ・・・・・・・・・・・・・・・・・・・・A
// プロパティ
private var
_plusFlg:Boolean;
private var
_minusFlg:Boolean;
private var
_saveData:String;
/**
* コンストラクタ
*/
public function
CalclationProxy():void
{
// 親クラスのコンストラクタの呼び出し。
// 第1引数は自分を示す文字列のNAMEを、
// 第2引数はプロパティとして保持する型を
// new演算子で指定してあげる。
// こうすることで第2引数に指定された型が
// dataというプロパティの型が設定される。
super(NAME,
new String ); ・・・・・・・・・・・・・・・・・・・B
_plusFlg
= false;
_minusFlg
= false;
_saveData
= "";
}
/**
* プロパティ値の取得
*/
public function get
calcString():String ・・・・・・・・・・・・・・・・・・C
{
// dataという型のプロパティをキャストして(ここではStringにして)返却
return data as String; ・・・・・・・・・・・・・・・・・・D
}
/**
* プロパティ値の設定
* 文字列を引数として渡された場合については
* 既存の文字列と結合する。
*/
public function set
calcString(s:String):void ・・・・・・・・・・・・・・・・E
{
if(_plusFlg == true )
{
_saveData
= calcString;
data
= s;
}
else if(_minusFlg ==
true )
{
_saveData
= calcString;
data
= s;
}
else if( s.length ==
0)
{
data
= "";
}
else
{
data
+= s;
}
}
/**
* 文字列をプロパティに設定
*/
public function
setNumber(s:String):void ・・・・・・・・・・・・・・・・・・F
{
calcString
= s;
}
/**
* 計算結果をプロパティに設定
*/
public function
calcEqual():void ・・・・・・・・・・・・・・・・・G
{
var result:int;
if( this._plusFlg == true )
{
result
= int(this._saveData) + int(calcString)
calcString
= result.toString();
this._plusFlg = false;
this._minusFlg = false;
this._saveData = "";
}
else if( this._minusFlg ==
true )
{
result
= int(this._saveData) - int(calcString)
calcString
= result.toString();
this._plusFlg = false;
this._minusFlg = false;
this._saveData = "";
}
}
/**
* 足し算するためのフラグをONにする
*/
public function
plusNumber():void ・・・・・・・・・・・・・・・H
{
this._plusFlg = true;
this._minusFlg = false;
}
/**
* 引き算するためのフラグをONにする
*/
public function
minusNumber():void ・・・・・・・・・・・・・・・I
{
this._plusFlg = false;
this._minusFlg = true;
}
/**
* すべてのクリア
*/
public function
clear():void ・・・・・・・・・・・・・J
{
calcString
= "";
this._saveData = "";
this._plusFlg = false;
this._minusFlg = false;
}
}
}
@ public class CalclationProxy extends Proxy implements IProxy
Proxyクラスの宣言部。
ここではProxyクラスの継承とIProxyインターフェースの実装を宣言しています。
Proxyクラスそのものは振る舞いを持っているわけではありません。
このクラスはビジネスロジックを実装するためのクラスであり、
親クラスであるProxyとインターフェースであるIProxyはFacadeクラスへ登録するためのクラスの型と
捉えることができます。
つまりFacadeクラスにビジネスロジックを登録したい場合にはこのProxyクラスを継承しIProxyのインターフェースを
実装しなければなりません。
A
public static const NAME:String = "CalclationProxy"
Facadeクラスに登録するための名前をここで定義しています。
ここで定義された名称でFaçadeクラスの中にインスタンスが生成されます。
よって、この名前はアプリケーションの中でユニークになっている必要があります。
B
super(NAME, new String );
Proxyクラスのコンストラクタを呼び出しています。
引数として文字列、オブジェクトの「型」を渡すのですが、
第1引数である文字列は自分のインスタンス名が何であるかを、自分自身が知るために渡すためのもので、
前述のAで指定したものを渡せば良いです。
第2引数はオブジェクトの「型」を渡すといっていますが、ここでいう第2引数はどのような役割を
もつのでしょうか。
Proxyクラスはビジネスロジックを実装するためのクラスであることは既に述べました。
このビジネスロジックで必要となるであろう、privateなインスタンス変数(クラス変数ともとれます)の
オブジェクトの型をこの第2引数によって決定しています。
このprivateなインスタンス変数は「data」という名称で親クラスであるProxyクラスに定義されており、
この「data」という変数に対して「型」を与えることができるのが第2引数というわけです。
つまりStringを第2引数に渡せば「data」はString型になるし、
Arrayを渡せば「data」はArray型になります。
C
public function get calcString():String
前述にある「data」を取得するメソッドです。
dataとしてそのままアクセッサメソッドを定義してもよかったのですが、
dataはprivateで定義されたものです。
ですので、アクセッサメソッドを用意してあげることでdataへのアクセスが
できるように用意しました。
D
return data as String;
dataをString型として返却しています。
前述のBでdataの型は定義されているのですが、ここでも明示的に型を示すことにより、
暗黙的なキャストをしないようにしています。
E
public function set calcString(s:String):void
dataへ値をセットするアクセッサメソッドです。
Cと同様です。
privateで定義されたdataへの値設定メソッドです。
F
public function
setNumber(s:String):void
ビジネスロジックです。
View層で押された「0〜9」までの数字ボタンに応じて、インスタンス変数のdata(このロジックでは直接dataにセットするわけではなく
アクセッサメソッドを通じてdataにセットしています)に文字列を設定します。
G
public function
calcEqual():void
ビジネスロジックです。
View層で「=」ボタンを押下した際に呼び出すためのメソッドです。
インスタンス変数のplusFlgとminusFlgの判定により、
足し算または引き算をした結果をインスタンス変数のdataに設定しています。
H
public function
plusNumber():void
ビジネスロジックです。
View層で「+」ボタンを押下した際に呼び出すためのメソッドです。
plusFlgをtrueにしてminusFlgをfalseにしています。
I
public function minusNumber():void
ビジネスロジックです。
View層で「−」ボタンを押下した際に呼び出すためのメソッドです。
minusFlgをtrueにしてplusFlgをfalseにしています。
J
public function clear():void
ビジネスロジックです。
View層で「C」ボタンを押下した際に呼び出すためのメソッドです。
インスタンス変数のdataとplusFlg、minusFlgを初期化しています。
次にValueObjectクラスです。
といっても、解説するほどのものではありませんが、とりあえず。
「CalclationVO.as」
package
example.model.vo
{
/**
* 計算結果等を保持するVOクラス
*/
[Bindable] ・・・・・・・・・・・・・・・・・・・・・・・@
public class
CalclationVO ・・・・・・・・・・・・・・・・・・・・・・・A
{
// プロパティ
private var
_calcString:String; ・・・・・・・・・・・・B
/**
* コンストラクタ
*/
public function
CalclationVO():void ・・・・・・・・・・・C
{
this._calcString
= "";
}
/**
* GETTER
*/
public function get
calcString():String ・・・・・・・・・・・・・・・・・・D
{
return this._calcString;
}
/**
* SETTER
*/
public function set
calcString(s:String):void ・・・・・・・・・・E
{
this._calcString
= s;
}
}
}
@ [Bindable]
Bindable宣言です。
このクラスはView層で表現する値(ここで言えば計算機のボタンを押したときの文字の表示)を保持するため、
クラス全体をバインディングします。
A public class CalclationVO
クラス名です。
ValueObjectクラスとわかりやすくするためにクラス名+VOとしています。
Cairngormの場合、ValueObjectインターフェースを実装していましたが、
PureMVCの場合には実装する必要はなくただのクラスとして定義します。
B private var
_calcString:String
インスタンス変数です。
C public function
CalclationVO():void
コンストラクタです。
この中でインスタンス変数を初期化しています。
D public function get
calcString():String
ゲッターメソッドです。
インスタンス変数の値を返却します。
E public function set
calcString(s:String):void
セッターメソッドです。
インスタンス変数に値を設定します。
Model層はここまでです。
ここもまたFlexのCairngormと違うことがわかります。
Cairngormを元としているPureMVCですが、基本的には別ものですので、
注意が必要です。
Model層といってもView層と交錯するVOクラスがいますが、
VOクラス自体のインスタンスはView層が持っていますので、
厳密に言えば、View層の値を表現するVOクラスはView層に属するといえるかもしれませんが、
VOにアクセスするクラスがProxyクラスであり、そのProxyクラスはModel層なので、
ここに分類しました。