feb19.jp

Nobuhiro Takahashi
Designer / Engineer

AS3 で GoF デザインパターン [11] - Composite

ActionScript 3.0 で Gang of Four デザインパターン [11] - Composite パターン

再帰的な構造をクラスで表現するためのパターンらしいです。再帰的って意味わかんないですね。入れ子構造とかになる構造のことだと思います。

別の言い方をすると木構造を持つデータを表したいときに使われるパターンです。

AS3 の DisplayObjectContainer ツリーとかまさにこのパターンを利用しているので、ActionScript プログラマーなら誰しも DisplayObjectContainer ツリーを参考にしていつの間にか作ったことがあった的な典型的デザインパターンかもしれません。

ディレクトリ構造など複雑な階層構造を持つデータをビジュアライズするときとかに使えます。

wikipedia での Java 実装例を参考にしました。

IFile.as
package jp.feb19.gof.composite
{
	public interface IFile
	{
		function get name():String;
		function get children():Array;
		function add(file:IFile):Boolean;
		function remove(file:IFile):Boolean;
		function defaultMethod(depth:int):void;
	}
}
File.as
package jp.feb19.gof.composite
{
	public class File implements IFile
	{
		private var _name:String;
		
		public function File(name:String)
		{
			_name = name;
		}
		
		public function get name():String
		{
			return _name;
		}
		
		public function get children():Array
		{
			return null;
		}
		
		public function add(file:IFile):Boolean
		{
			return false;
		}
		
		public function remove(file:IFile):Boolean
		{
			return false;
		}
		
		public function defaultMethod(depth:int):void
		{
			var s:String = "";
			for (var i:int = 0; i <depth; i++) s += " ";
			trace(s + "file: " + this.name);
		}
	}
}
Folder.as
package jp.feb19.gof.composite
{
	public class Folder implements IFile
	{
		private var _name:String;
		private var _children:Array;
		public function Folder(name:String)
		{
			_children = [];
			_name = name;
		}
		
		public function get name():String
		{
			return _name;
		}
		
		public function get children():Array
		{
			return _children;
		}
		
		public function add(file:IFile):Boolean
		{
			_children.push(file);
			return true;
		}
		
		public function remove(file:IFile):Boolean
		{
			var children:Array = _children;
			var l:uint = children.length;
			for(var i:int = 0; i<l;i++)
			{
				if (children[i] === file)
				{
					_children.splice(i, 1)
					return true;
				}
			}
			
			return false;
		}
		
		public function defaultMethod(depth:int):void
		{
			var s:String = "";
			for (var i:int = 0; i <depth; i++) s += " ";
			trace(s + "folder: " + this.name);
			for each (var file:IFile in _children)
			{
				file.defaultMethod(depth + 1);
			}
		}
	}
}

テストクラス。

package jp.feb19.gof.composite
{
	import flash.display.Sprite;
	
	public class CompositeTest extends Sprite
	{
		public function CompositeTest()
		{
			super();
			
			var root:IFile = new Folder("root");
			var lib:IFile = new Folder("lib");
			var apps:IFile = new Folder("apps");
			var application:IFile = new File("applicationA");
			var home:IFile = new Folder("home");
			var user1:IFile = new Folder("user1");
			var file:IFile = new File("file1");
			
			root.add(lib);
			lib.add(apps);
			root.add(home);
			home.add(user1);
			user1.add(file);
			apps.add(application);
			
			root.defaultMethod(0);
		}
	}
}
出力:
folder: root
 folder: lib
  folder: apps
   file: applicationA
 folder: home
  folder: user1
   file: file1
Tweet Share Bookmark

Navigation

prev: AS3 で GoF デザインパターン [10] - Strategy
next: AS3 で GoF デザインパターン [12] - Decorator

Recently Entries