当我们的一个对象可能代表一个单一的实体,或者一个组合的实体,但是仍然需要通过同样的方式被使用时,这种情形则适合使用组合模式的设计。
组合模式Composite将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
适用性:
当需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。
角色:
树干——基类、树枝——组合对象、树叶——局部对象
例:
abstract class CompanyBase{
//节点名称
protected $name;
public function _construct($name){
$this->name = $name;
}
public function getName(){
return $this->name;
}
//增加节点
abstruct function add(CompanyBase $c);
//删除节点
abstruct function remove(CompanyBase $c);
//输出节点信息
abstruct function show($deep);
//节点职责
abstruct function work($deep);
}
//公司类
class Company extends CompanyBase{
protected $item = [];
public function add(){
$nodeName = $c->getName();
if(!isset($this->item[$nodeName])){
$this->item[$nadeName] = $c;
}else{
throw new Exception("该节点已存在,节点名称:".$nodeName);
}
}
public function remove(CompanyBase $c){
$nodeName = $c->getName();
if(isset($this->item[$nodeName])){
unset($this->item[$nodeName]);
}else{
throw new Exception("该节点不存在,节点名称:".$nodeName);
}
}
public function show($deep=0){
echo str_repeat("-",$deep).$this->name;
echo "
";foreach($this->item as $value){
$value->show($deep+4);
}
}
public function work($deep = 0){
foreach($this->item as $value){
echo str_repeat("$emsp",$deep)."[{$this->name}]
";$value->work($deep+2);
}
}
/*
*人力资源部
*/
class HumanResources extends CompanyBase{
public function add(CompanyBase $c){
throw new Exception("该节点下不能增加节点");
}
public function remove(CompanyBase $c){
throw new Exception("该节点下无子节点");
}
public function show($deep = 0){
echo str_repeat("-", $deep).$this->name;
echo "
";}
public function work($deep = 0){
echo str_repeat(" ", $deep)."人力资源部门的工作是为公司招聘人才";
echo "
";}
}
/*
*商务部门
*/
class Commerce extends CompanyBase{
public function add(CompanyBase $c){
throw new Exception("该节点下不能增加节点");
}
public function remove(CompanyBase $c){
throw new Exception("该节点下无子节点");
}
public function show($deep = 0){
echo str_repeat("-", $deep).$this->name;
echo "
";}
public function work($deep = 0){
echo str_repeat(" ", $deep)."商务部门的工作是为公司赚取利润";
echo "
";}
}
$c = new Company("北京某科技公司");
$h = new HumanResources("人力资源部门");
$com = new Commerce("商务部门");
$c->add($h);
$c->add($com);
//天津分公司
$c1 = new Company("天津分公司");
$c1->add($h);
$c1->add($com);
$c->add($c1);
//武汉分公司
$c2 = new Company("武汉分公司");
$c2->add($h);
$c2->add($com);
$c->add($c2);
$c->show();
$c->work();
特点:
1、必须存在不可分割基本元素。
2、组合后的物体可以被组合。