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

要は clone() です。BitmapData.clone() や Event.clone() など、クラス内にインスタンス自身をコピーするメソッドを用意することです。

function clone():Protoype
{
     return new Prototype(this.param, this.value, this.data);
}

的な感じで、自身の特徴をパラメータで渡して同様のインスタンスを作れるようにしておき、return で返してやるというのが一般的です。

ディープコピー

AS3 の ByteArray を使うことで、インスタンスの情報を丸々コピーするディープコピーという手法があるのでついでに使ってみます。

ActionScript: IClonable.as

package jp.feb19.gof.prototype
{
	public interface IClonable
	{
		function clone():*;
	}
}

ActionScript: Prototype.as

package jp.feb19.gof.prototype
{
	import flash.utils.ByteArray;
	
	public class Prototype implements IClonable
	{
		private var _name:String;
		
		public function Prototype()
		{
		}
		
		public function clone():*
		{
			var bytes:ByteArray = new ByteArray();
			bytes.writeObject(this);
			bytes.position = 0;
			
			return bytes.readObject();
		}
		
		public function get name():String
		{
			return _name;
		}
		
		public function set name(value:String):void
		{
			_name = value;
		}
		
	}
}

ActionScript: Human.as

package jp.feb19.gof.prototype
{
	public class Human extends Prototype
	{
		private var _age:int;
		
		public function Human(name:String, age:int)
		{
			super();
			this.name = name;
			_age = age;
		}
		
		override public function get name():String
		{
			return super.name + ": " + _age.toString();
		}
	}
}

テストクラス

ActionScript: PrototypeTest.as

package jp.feb19.gof.prototype
{
	import flash.display.Sprite;
	
	public class PrototypeTest extends Sprite
	{
		public function PrototypeTest()
		{
			super();
			
			var human:Human = new Human("unko", 10);
			var cHuman:Object = human.clone();
			trace(human.name);
			trace(cHuman.name);
			trace(cHuman == human);
		}
	}
}

出力

unko: 10
unko: 10
false

比較文で同じインスタンスではないということが分かります。