はい、第四回目はFactory Methodです。
出てくる登場人物は5人
・Factory.as
・Product.as
・IDCard.as
・IDCardFactory.as
・Main.as
ひな形の役割のFactory.asさんとProduct.asはインターフェースがあるだけで、実際のインスタンス化はサブクラスのお二人、IDCard.asさんとIDCardFactory.asさんにお任せってパターンです。
今回は参考書の方はpackageを使ってまして、せっかくなんでActionScript 2.0版のほうも使ってみました。いままでpackageを使ったこと無かったんでちょっと手間取りました。
基本的にはフォルダを切ってそこに書いたクラスを放り込むような感じで、classの命名のところでhogepackage.hogeclassとするとオーケーみたい。importするときはjavaとかとおんなじで、
import hogepackage.*;
と、パッケージを使いたいclassの文頭に書いておくと、そのパッケージ内のクラスをパブリッシュするときに勝手にサーチしてくれる。まあ、importなくても、文中にhogepackage.hogeclassといった感じに書けば動くことは動きますが、面倒だし、パッケージをまとめとけば後々いいことありそうな雰囲気。というか、覚えておこう。
この辺は本題とは直接関係ないです。
では、順番にみてきましょう。
// framework/Factory.as import framework.*;class framework.Factory extends Product{
function create(owner:String){
var p = createProduct( owner );
registerProduct(p);
return p;
}
function createProduct(owner:String){}
function registerProduct(product:Product){}
}
// framework/Product.as class framework.Product{ function use():String{return "";}; }
この二つは大枠のひな形に相当するclass。前回のtemplate methodと同じくjava版ではinterfaceが使われてたのですけど、Factoryクラスのcreateメソッドのところで大まかな処理(実体なし)をしてるのでこんな感じにしてみました。createメソッドのところが今回のポイントですね。
で、実際にインスタンス化するのが下の二つ。
// idcard/IDCard.as import framework.*;class idcard.IDCard extends Product{
private var owner:String;
function IDCard(o:String){
owner = o;
trace( owner+"のカードを作ります");
}
function use():String{
return owner+"のカードを使います";
}
function getOwner():String{
return owner;
}
}
いままではswfに文字を表示させる仕様にしていたのですが、それだと、コンストラクタのところで戻り値を指定しなきゃいけないくてつまづいちゃいました。結局やり方がわかんないので、trace文にしとくことに。。ということで、ムービーには表示されません。パターンの大枠の流れを把握しとくのが先なのでとりあえずスキップ。
※mtascだとjavac.jpさんが提供している JTracer というツールを使うと表示できます。jp.javac.toolsをインポートして普段trace(hoge)と書いているところをJTracer.trace(hoge)と書いた後、まず、JTracerを立ち上げます。その後にパブリッシュしたswfを再生します。すると、JTracer上にtrace文の内容が表示されます。
// idcard/IDCardFactory.as import framework.*; import idcard.*;class idcard.IDCardFactory extends Factory {
private var owners:Array;
function IDCardFactory (){
owners = new Array();
}
function createProduct(owner:String):Product{
return new IDCard(owner);
}
function registerProduct(product:Product){
owners.push( product );
}
}
Factory.asで大枠の処理を書いてあるので、具体的にIDCardのインスタンスをどう使うかが書かれてます。
最後にMain.as
//Main.as import idcard.*;class Main{
// メインクラス
function Main(path :MovieClip ) {
var factory = new IDCardFactory();
var card = [];
card[0] = factory.create("佐藤魚");
card[1] = factory.create("さとう");
card[2] = factory.create("さかな");var tmp ="";
for(var i=0 ; i < card.length ;i++){
tmp = tmp+card[i].use()+"¥n";
}
// 表示
path.createTextField("tf", 1, 5, 5, 190, 190);
path.tf.border = true;
path.tf.multiline= true;
path.tf.wordWrap= true;
path.tf.text = tmp;
}
static function main() {
var t :Main= new Main(_root);
}
}
でmtascから
mtasc -swf factoryMethod.swf -main Main.as -header 200:200:30
とすると、動きます。
うーん今回はちょっと理解しづらくて手こずりました。
参考書のクラス図を解読していって何となくわかった感じ。
前回のTemplate Methodと似ているのだけど、あっちは処理の流れをテンプレートが決めごとを作ってるのに対して、こっちは、インスタンス化のしかたを工場(Factory)が決めているイメージなのかなと理解。
ということで、また。