php实现设计模式之 组合模式

<?php
/**
 * 组合模式
 *
 * 将对象组合成树形结构以表示"部分-整体"的层次结构,使得客户对单个对象和复合对象的使用具有一致性
 * 
 * 
 * 
1)       抽象构件角色Component:它为组合中的对象声明接口,也可以为共有接口实现缺省行为。
2)       树叶构件角色Leaf:在组合中表示叶节点对象——没有子节点,实现抽象构件角色声明的接口。
3)       树枝构件角色Composite:在组合中表示分支节点对象——有子节点,实现抽象构件角色声明的接口;存储子部件。
 */

/*
 * 以典型的目录构造为例
 * 我想建造一个newfile目录,下面有music和novel两个文件夹,music下放置音乐文件,novel下放置小说txt
 * 
 */

//抽象构件角色:对象接口,添加子节点,删除子节点,展示目录结构
class dir{
	public function add($component){}
	public function remove($component){}
	public function display(){}
}

//树叶构件:树叶没有子节点,不存在add,remove方法,只有展示放啊
class leaf extends dir{
	public $name;
	public function __construct($name){
		$this->name = $name;
	}
	
	public function display(){//树叶只展示自身名字即可
		echo $this->name;
	}
}

//树枝构件
class file extends dir{
	public $name;
	public $items=array();
	public function __construct($name){
		$this->name = $name;
	}
	
	public function add($component){//添加子节点
		$this->items[] = $component;
	}
	public function remove($component){//删除子节点
		$key = array_search($component,$this->items);
		if ($key!==false){
			unset($this->items[$key]);
		}
	}
	
	public function display(){//树枝节点不止展示本身,而且展示其子节点
		echo $this->name.'----';//本身
		foreach ($this->items as $key=>$value){//子节点若还是树枝,递归调用; 子节点若是树叶,只展示本身
			if (is_object($value)){
				$value->display();
			}else{
			echo $value->name.'--';
		}
		}
	}
}

//构造过程从底层开始
$leaf1 = new leaf('a.mp4');
$leaf2 = new leaf('b.mp4');
$file1 = new file('music');
$file1->add($leaf1);
$file1->add($leaf2);
$file1->remove($leaf1);
//$file1->display();
$leaf3 = new leaf('a.txt');
$leaf4 = new leaf('b.txt');
$leaf5 = new leaf('c.txt');
$file2 = new file('novel');
$file2->add($leaf3);
$file2->add($leaf4);
$file2->add($leaf5);
//$file2->display();
$dir = new file('newfile');
$dir->add($file1);
$dir->add($file2);
$dir->display();
?>

  UML类图如下:

posted @ 2014-11-04 12:01  tai君  阅读(341)  评论(0编辑  收藏  举报