パラメータコンテナのテスト
汎用パラメータコンテナクラスのテストコード 2010/08/22
*
* Tweener.addTween() などにおいて {name: value, ... } の形式で
* パラメータを渡しますが、自身のコードでこのようなパラメータを汎用的に
* 制御したい場合どうすればよいか?ということで、基底パラメータコンテナ
* となるクラス BaseParamContainer を作ってみました。
*
* 基底クラスを継承した(自分の使いたい)パラメータコンテナを定義し、
* コンテナを生成する際に {name: value, ... } の形式でパラメータを
* 流し込むイメージです。強制的に型が合うものを設定するだけのシンプルな
* 構造であるため定義側も呼出側も扱いは難しくないと考えます。
*
* 現在作っている表示オブジェクトの Link クラス用のパラメータとして
* この仕掛けを使おうと思ってます。極小規模の開発では、この手の枠組みは
* 冗長だと考えますが、部品群の開発と表面側の実装が分かれるような
* 開発シーンで、多くのパラメータを受け渡しする場合、便利だと思いますが
* どうでしょう?
/**
* Copyright zier ( http://wonderfl.net/user/zier )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sLT1
*/
/*
* 汎用パラメータコンテナクラスのテストコード 2010/08/22
*
* Tweener.addTween() などにおいて {name: value, ... } の形式で
* パラメータを渡しますが、自身のコードでこのようなパラメータを汎用的に
* 制御したい場合どうすればよいか?ということで、基底パラメータコンテナ
* となるクラス BaseParamContainer を作ってみました。
*
* 基底クラスを継承した(自分の使いたい)パラメータコンテナを定義し、
* コンテナを生成する際に {name: value, ... } の形式でパラメータを
* 流し込むイメージです。強制的に型が合うものを設定するだけのシンプルな
* 構造であるため定義側も呼出側も扱いは難しくないと考えます。
*
* 現在作っている表示オブジェクトの Link クラス用のパラメータとして
* この仕掛けを使おうと思ってます。極小規模の開発では、この手の枠組みは
* 冗長だと考えますが、部品群の開発と表面側の実装が分かれるような
* 開発シーンで、多くのパラメータを受け渡しする場合、便利だと思いますが
* どうでしょう?
*/
package {
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.utils.describeType;
import com.bit101.components.PushButton;
[SWF(width=465, height=465)]
public class FlashTest extends Sprite {
private var memo: TextField
public function FlashTest() {
function createTextField(p: DisplayObjectContainer, x: Number, y: Number, w: Number, h:Number): TextField {
var t: TextField = new TextField()
t.x = x; t.y = y; t.width = w; t.height = h; p.addChild(t)
return t
}
function createButton(p: DisplayObjectContainer, x: Number, y: Number, c: String, f: Function): PushButton {
return new PushButton(p, x, y, c, f)
}
var title: TextField = createTextField(this, 10, 10, 200, 20)
title.scaleX = title.scaleY = 2
title.text = "BaseParamContainer test code"
createButton(this, 10, 50, "case 1", case1).width = 60
createButton(this, 80, 50, "case 2", case2).width = 60
createButton(this, 150, 50, "case 3", case3).width = 60
createButton(this, 220, 50, "case 4", case4).width = 60
createButton(this, 290, 50, "case 5", case5).width = 60
createButton(this, 360, 50, "case 6", case6).width = 60
memo = createTextField(this, 10, 80, 430, 360)
memo.wordWrap = true
memo.border = true
}
private function init(msg: String): void { memo.text = msg + "\n-----" }
private function list(param: Object): void {
for each(var variable:XML in describeType(param)..variable) {
var n: String = variable.@name
memo.appendText("\n" + n + ":" + param[n])
}
}
private function case1(e: MouseEvent = null): void {
init("test case 1:\nそのままパラメータコンテナを生成した場合\nデフォルト値を使ったパラメータコンテナを生成する")
list(new SampleParam())
}
private function case2(e: MouseEvent = null): void {
init("test case 2:\nパラメータを渡してコンテナを生成した場合\n渡されたパラメータに従って、内容を更新できる")
list(new SampleParam( { tail: this, lineWidth: 5, lineColor: 0xff0000, fillColor: 0xc00000, fill: true } ))
}
private function case3(e: MouseEvent = null): void {
init("test case 3:\nstatic な factory method を使う事も問題なし\nこれで呼出側に対して、複数のデフォルトパラメータを提供できる")
list(SampleParam.create())
}
private function case4(e: MouseEvent = null): void {
init("test case 4:\nプリミティブ型に対して型が違うパラメータを渡した場合は、\n設定は無視され、デフォルト値が優先される")
list(new SampleParam( { fillColor: "A" } ))
}
private function case5(e: MouseEvent = null): void {
init("test case 5:\nパラメータ名称がマッチしない内容を渡した場合\nコンテナに追加されるのではなく、無視される")
list(new SampleParam( { a: "A" } ))
}
private function case6(e: MouseEvent = null): void {
init("test case 6:\n型が異なるオブジェクトを渡された場合はエラー\nこの例外制御は呼出側に任せる")
try {
list(new SampleParam( { head: new Object() } ))
} catch (ex: TypeError) {
memo.appendText("\n" + ex.message)
}
}
}
}
// --------------------------------------------------
// 基底パラメータコンテナクラス (Abstract) : 継承時 コンストラクタで super(this, obj) を呼ぶこと
class BaseParamContainer {
private function inject(o: Object): void {
for (var n: String in o) if (this.hasOwnProperty(n)) this[n] = o[n]
}
public function BaseParamContainer(access:*= null, obj: Object = null) {
if (access != this) throw new Error("AbstractException")
inject(obj)
}
}
// --------------------------------------------------
// サンプル パラメータクラス
import flash.display.DisplayObject;
class SampleParam extends BaseParamContainer {
// inject するためパラメータは public とすること (カプセル化を壊すが利便性を優先)
public var tail: DisplayObject
public var head: DisplayObject
public var lineWidth: uint = 1
public var lineColor: uint = 0x000000
public var fillColor: uint = 0x000000
public var fill: Boolean = false
// factory method sample : 若干異なるパラメータで生成したい場合に利用
public static function create(obj: Object = null): SampleParam {
var result: SampleParam = new SampleParam(obj)
result.lineWidth = 2;
result.lineColor = 0xFF0000;
return result
}
// コンストラクタでは必ず super() を適切に呼ぶこと
public function SampleParam(obj: Object = null) { super(this, obj) }
}