cheka.jp 超不定期で更新する写真達。お口直しにどうぞ。

[写経] PHPで学ぶデザインパターン12

— 注意 —
PHPによるデザインパターンの写経ですが、まんま書くと問題があるのでアウトプットとして備忘録メモです

Compositeで木構造を表現する

構造 + オブジェクト

ファイルツリーのような木構造を表現するのに適したパターンです。
データ生成に対して同一のAIPを提供することで、木構造に対するユーザー操作を簡単にする事が可能になります。

共通のAPIを提供する親クラスを定義

APIを共通化するための親クラスを定義します。
ルートクラスとリーフクラスはここで定義したクラスを継承させます。

/*
Componentクラス
*/	
abstract class OrganizationEntry
{
	private $code;
	private $name;
	
	//コンストラクタ
	public function __construct($code,$name)
	{
		$this->code = $code;
		$this->name = $name;
	}
	
	//コードの取得
	public function getCode()
	{
		return $this->code;
	}
	
	//名称の取得
	public function getName()
	{
		return $this->name;
	}
	
	//デバック用
	public function dump()
	{
		print $this->getCode().":".$this->getName()."\n";
	}
		
	//データの追加
	abstract function add(OrganizationEntry $entry);
	
}

木構造を表現するクラスの定義

まずはルートクラスからです。

/*
Groupクラス
*/
class Group extends OrganizationEntry
{
	//子要素
	private $entries;

	//コンストラクタ
	public function __construct($code,$name)
	{
		parent::__construct($code,$name);
		$this->entries = array();
	}
	
	//子要素の追加
	public function add(OrganizationEntry $entry)
	{
		array_push($this->entries,$entry);
	}
	
	//デバック用
	public function dump()
	{
		//自分の情報
		parent::dump();
		//デバック
		foreach ($this->entries as $entry) {
			$entry->dump();
		}
	}
}

次にリーフとなるクラスです。

/*
Employeeクラス
*/
class Employee extends OrganizationEntry
{
	//コンストラクタ
	public function __construct($code,$name)
	{
		parent::__construct($code,$name);		
	}

	//子要素の追加
	public function add(OrganizationEntry $entry)
	{
		throw new Exception('Employeeクラスで子要素は追加出来ません');
	}	
}

使ってみる

本社支店に社員を追加してみましょう。

$group = new Group("001","本社");

$group->add(new Employee("E01","emp001"));
$group->add(new Employee("E02","emp002"));
$group->add(new Employee("E02","emp003"));

$group->dump();
$php composite.php
001:本社
E01:emp001
E02:emp002
E02:emp003

仮に事業所単位の追加を求められても簡単に対応出来そうですね!

Add a Comment

メールアドレスが公開されることはありません。