二回目はAdapter(一皮かぶせて再利用)です。これは普段からAdapterとか言う単語を知る前から自然に使ってたので簡単に理解できました。
このパターンの勘所は元々提供されているClassがあって(今回はBanner.as)クライアント(Main.as)が新しいインターフェース(Print.as)に適合させる必要がある場合、ずれを埋める役目(PrintBanner.as)すなわちAdapterを用意すれば元々提供されているClassを書き換えなくてもオッケーじゃん、便利じゃん。というところです。
やり方としては、「継承」と「委譲」というのがあって、いきなり非日常単語が出てくるのですが、ビビる必要はなし。要は「引き継ぎ式」と「お任せ式」ってことですね。それぞれのソースを書いてみました。
■「継承」の場合
これが、今回のネタもと。こんなClassがすでに書かれてましたと仮定してます。
// Banner.as class Banner{ private var string:String; function Banner(s:String){ string = s; } function showWithParen():String{ return "(" + string + ")" ; } function showWithAster():String{ return "*" + string + "*"; } }
で、新たに用意されるインターフェースというのがこれ。
// Print.as interface Print{ function printWeak():String; function printStrong():String; }
上の二人をくっつける役目すなわちAdapterというかキューピッドさん役がこれです。今回のストーリーの主役ですね。Bannerクラスを拡張して、Printインターフェースの実装が書かれてます。
// PrintBanner.as class PrintBanner extends Banner implements Print{ function PrintBanner(s:String){ super(s); } function printWeak():String{ return showWithParen(); } function printStrong():String{ return showWithAster(); } }
で、Mainがこんな感じ。参考書(「増補改訂版Java言語で学ぶデザインパターン入門」結城 浩)通りに書くとtraceを使うのだろうけど、めんどうだからmtasc単体で検証したかったのでムービー自体に表示させてます。それにあわせてその他のClass も原典からいじってます。
//Main.as class Main{ function Main(path :MovieClip ) { var p = new PrintBanner("Hello"); var tmp = p.printWeak(); tmp = tmp +"¥n"+ p.printStrong(); // 表示 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); } }
普段使い慣れているパターンを改めて説明されると、なるほどと納得するところがあった。つまり一個一個のClassだけ注目してるとデザインパターンってよくワカンナくなっちゃうけど、クラスどうしの関係を読んでいくと納得できるんですね。なるほど。別々に育った二人を巡り会わせるキューピッドさんのストーリーみたいなパターンかあ、と読んでいくと納得できる。
よし、このコーナーはこんな調子で一つ一つのパターンを簡単なストーリーに置き換えていくようにしよう。
閑話休題。
で、次が「委譲」もとい、「お任せパターン」を使った場合のソース。
■「委譲」の場合
「継承」との大きな違いはPrint.asがインターフェースから、クラスになってるところかな。こっちのほうが使用する機会が多いと聞いたことがある。Print.asとPrintBanner.as以外は同じ。
// Print.as class Print{ function printWeak():String{ return ""; } function printStrong():String{ return ""; } }
traceじゃなくてstringを返すようにしたので、こんな感じになった。けど、return文の所ってこれじゃなんか変だよなあ。まあとりあえず今のところはこのままで。
次がAdapterもといキューピッドさんのPrintBanner.as(お任せ式)
// PrintBanner.as class PrintBanner extends Print{ private var banner:Banner; function PrintBanner(s:String){ banner = new Banner(s); } function printWeak():String{ return banner.showWithParen(); } function printStrong():String{ return banner.showWithAster(); } }
キモは、implementsで引き継ぎをしていたところを、インスタンスを一個作って、その人にお任せしてるところ。
なあるほどね。
ということで次回に続く。