「クラス(インスタンスではない)を条件によって振り分けたい」と試行錯誤したメモ。
「Class型でクラス定義を管理するとこういう事も出来る」というサンプルです。
「Class型でクラス定義を管理するとこういう事も出来る」というサンプルです。
問題
例えば、「拡張子が flv の時は flvVideo クラス、拡張子が swf の時は swfPlayer クラス、どちらも mediaStream クラスを継承していて、制御は mediaStream クラスのメソッド&プロパティから行う。」と言う場合。拡張子毎の切り替えコードは、普通に書けば以下のような素直な物になるでしょう。
var screen:mediaStream;
switch(extension.toLowerCase())
{
case "flv":
screen = new flvVideo();
break;
case "swf":
screen = new swfPlayer();
break;
}
もっとエレガントなやり方が有るような気がしてなりません。
と言うわけで、「class as3」等で検索してみました。
「flash.utils.getDefinitionByName() を使って文字列でクラスを云々~」と言うページが沢山ヒットします。
しかし、動的にクラス定義の切り替えをするだけならば、「これを使わずに出来るんではなかろうか?」という直感の下、Classクラスで色々やってみるうちに、ソレっぽくなりました。
var screen:mediaStream;
var classArray:Object =
{
flv:flvVideo,
swf:swfPlayer
};
var classObject:Class = classArray[extension.toLowerCase()];
screen = new(classObject)();
getDefinitionByName と違い、クラス定義への参照が配列の中に有るので、「コードのどこかでクラスを読み込んでいなければならない」という事もありません。
なにより、今後の拡張は classArray に「拡張子と mediaStream サブクラスの関連付け」を追加するだけで済みます。
この例のコードではコンストラクタに引数を取りませんでしたが、以下のようにすれば引数を付加は容易です。
screen = new(classObject)(initWidth:Number, initHeight:Number);
雑感
本当は、インターフェースを使っておしゃれにコーディングしたかった。の、ですが、DisplayObject を継承しなければならなかったり、インターフェースどころか内容記述が同じ関数を何度も書かなければならない可能性が出てきたりで、結局クラス継承で作った経緯をメモしたモノだったりします。
「エレガントなコードを書ける≒良い設計が出来る」と信じて今年も精進してまいりたいと思います。

コメントする