- 2007-01-08 (月) 16:19
- action script
「Decorate(飾る)」の言葉通り、何か機能を追加したいクラスがあった時、そのオリジナルを直接編集せず、その機能を引き継いだDecoratorクラスを作成し、そこで追加機能をトッピングしていく手法。
それならextend(継承)するのと一緒やん、と僕も思いましたが、
Decorator パターンデザインパターン[モデリング] -TECHSCORE-
様の記事を見て、その便利さが分かったような気がします。たしかに記事のような場合、継承する場合と比べて、クラスファイルの数をぐっと減らすことができますね。
どのクラスを機能拡張させるかを、あとからでも柔軟に選ぶことができる。こんな感じでしょうか。
「Object-oriented ActionScript for Flash 8」p183に、Decoratorパターンのベースとなるコードが書かれています。
コンストラクタの引数として、機能追加させたいクラスのインスタンスを受け取り、それをDecoratorクラスインスタンスの変数として内部に保持しておく。次に元クラスが持っていた各メソッドと同名のメソッドを定義していくのだけど、インスタンスメソッドの実行という形で、実際は先ほど保持したインスタンス変数のメソッドを動かすようにする。こうすることで元クラスと同じ機能を持つDecoratorクラスができあがる。
あとは、追加させたい機能をトッピングしていくわけですが、ここでも操作対象となるのは実はインスタンス内のインスタンス変数。
fla側でDecoratorクラスのインスタンスを生成する時は、
var myDecorator:Decorator = new Decorator(new baseClass);
パラメーターに元クラスのインスタンスを指定するのがポイント。
次に、具体例(p184~)を見ていくわけですが、ここで登場するのが__resolveという聞きなれないメソッド。Flashにもともとあるメソッドだそうで、ちゃんとヘルプファイルにも収録されています。パラメーターとして、実行させたいメソッド名のストリングを受け取るようになっているのですが、もし存在しないメソッド名を渡した場合、「そんな○○なんてメソッドは存在しないよ!」と教えてくれます。ただ、__resolveメソッドを実行するタイミングでチェックする仕様なので、クラスインスタンス作成時に型指定していたら、その時点で標準のFlashデバッガ側のチェックも入り、いつものエラー文も表示されてしまう。対応策として、コンストラクト時は型指定しないようにするという工夫が必要。
さらに__resolveはこのままでは、受け取ったメソッドのパラメーターを受け取れない。そこでapplyメソッドを使うことになります。このapplyメソッドは第1パラメーターとして対象となるオブジェクト、第2パラメーターargumentsに、__resolveが受け取ったメソッド名のパラメーター(もちろん複数個もOK)をarguments[0]のように、配列として保持できます。
以上の作業で、きちんと動くDecoratorパターンのサンプルが完成。別サンプルとして、ArrayクラスをDecorateして、配列内の要素の重複をチェックしたり、重複要素を削除させるメソッドを追加したArray2クラスを作成しています。ちょっと改造すれば、携帯電話の着信履歴のような処理ができそうです。
以上です。書籍では最後までextendとの使い分けがイメージしにくかったのですが、カシューナッツバニラアイスクリームと、カシューナッツ抹茶アイスクリームの記事で納得できました。
- Newer: monoface | shuffleface
- Older: FlashとSingletonパターン
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://www.trick7.com/blog/2007/01/08-161901.php/trackback
- Listed below are links to weblogs that reference
- FlashとDecoratorパターン from trick7