ActionScript 3 (Flash/AIR): GoF デザインパターン – Adapter

既に作られている物と必要な物の間のズレを、埋めるようなデザインパターンだそうです。新しい環境や別の環境上で動作させたいクラスがあるとして、その動作が安定しているクラス自体を改造するのではなく、変換役となるアダプターを用意して機能をラッピングする(なので Wrapper パターンとも言う)デザインパターンです。

動作の安定しているクラスを拡張する場合、継承(extends でサブクラス化すること)か委譲(内部でスーパークラスをインスタンス化しておいてスーパークラスへはサブクラスとするクラス経由でアクセスするようにする)を行って別クラス化するときに、Interface を実装するようにして、使用する側には動作の安定しているクラスを隠蔽する、という事だと思います。

ライブラリを作って API を提供するときとかに使ったりします。

ActionScript: Adaptee.as

package jp.feb19.gof.adapter
{
	public class Adaptee
	{
		private var _cost:int = 30;
		
		public function Adaptee()
		{
		}
		
		public function get cost():int
		{
			return _cost;
		}
	}
}

ActionScript: ITarget.as

package jp.feb19.gof.adapter
{
	public interface ITarget
	{
		function getPrice():int;
	}
}

継承を使って実現する Adapter1

ActionScript: Adapter1.as

package jp.feb19.gof.adapter
{
	public class Adapter1 extends Adaptee implements ITarget
	{
		public function Adapter1()
		{
			super();
		}
		
		public function getPrice():int
		{
			return this.cost + 10;
		}
	}
}

委譲を使って実現する Adapter2

ActionScript: Adapter2.as

package jp.feb19.gof.adapter
{
	public class Adapter2 implements ITarget
	{
		private var _product:Adaptee;
		public function Adapter2()
		{
			_product = new Adaptee();
		}
		
		public function getPrice():int
		{
			return _product.cost + 10;
		}
	}
}

テストクラス

ActionScript: AdapterTest.as

package jp.feb19.gof.adapter
{
	import flash.display.Sprite;
	
	public class AdapterTest extends Sprite
	{
		public function AdapterTest()
		{
			super();
			
			// 継承して拡張した Adapter1
			var target1:ITarget = new Adapter1();
			trace(target1.getPrice());
			
			// 委譲して拡張した Adapter2
			var target2:ITarget = new Adapter2();
			trace(target2.getPrice());
		}
	}
}

出力

40
40

隠蔽度合いでは委譲を使った方が隠蔽できてるので委譲の方がいいかも。継承だとそれしか継承できないし。シンプルですが。