Adapterパターンは、既存のクラスがクライアントに対して機能的に不十分である場合にそのクラスを改変することなくクライアントに適合させる方法である。 既存クラスに手を下さず機能を拡張するという意味ではサブクラスを作成する方法も一種のAdapterパターンと言える。
同様の機能を持つパターンとしてDecoratorパターンが挙げられる。両者の違いは、 DecoratorパターンにおけるDecoratorは既存クラスを継承している(既存クラスになりすます)必要があるのに対して、 AdapterパターンにおけるAdapterはクライアントに適合できればどのようなクラス構造であってもよいという点だろう。 またDecoratorパターンがオブジェクトに適用されるのに対してAdapterパターンはクラスに適用されるというのも大きな相違点である。
クライアント(main.as)はボクシングの試合に出場するボクサーを探しているが、あいにくキックボクサー(KickBoxer.as)しかいなかったとしよう。 このキックボクサーをボクシングの試合にそのまま出場させてキック(doKick)を放たれては非常に困ることが予想される。 そこでこのキックボクサーにAdapterパターンを施しボクサーとして矯正した状態でボクシングの試合に出場させることを試みる。 ここでは二つの異なるアプローチでAdapterパターンを実践している。
//main.as package { import flash.display.Sprite; public class main extends Sprite{ public function main(){ var boxer1:AdaptedBoxer = new AdaptedBoxer(); boxer1.doPunch();//Punch! var boxer2:InheritedBoxer = new InheritedBoxer(); boxer2.doPunch();//Punch! boxer2.doKick();//Punch! } } }
//KickBoxer.as (Adaptee) package{ public class KickBoxer{ public function KickBoxer(){ } public function doPunch():void{ trace("Punch!"); } public function doKick():void{ trace("Kick!"); } } }
//AdaptedBoxer.as (Composition adapter) package{ public class AdaptedBoxer{ protected var _kickBoxer:KickBoxer; public function AdaptedBoxer(){ _kickBoxer = new KickBoxer(); } public function doPunch():void{ _kickBoxer.doPunch(); } } }
//InheritedBoxer.as (Inheritance adapter) package{ public class InheritedBoxer extends KickBoxer{ public function InheritedBoxer(){ } override public function doKick():void{ //doKick is not allowded in a boxing match. this.doPunch(); } } }