组合模式将对象组合成树形结构以表示部分和整体的层次结构。组合模式使用户操作单个对象和组合对象具有一致性。

例如公司总部与公司的分部,在职能架构上是没什么区别的,可以当成一个整体,也可以把它单座一个整体的部分。

既然要具有一致性肯定需要公共接口:

abstract class Company {

protected $company = null;

public function __construct($company)
{
    $this->company = $company;
}

abstract public function add($name,Company $company);
abstract public function remove($name);
abstract public function show();
abstract public function exec();
}

具体实现类:

class ConcreteCompany extends Company {

protected $list = array ();
public function __construct($company)
{
    $this->company = $company;
}

public function add($name,Company $company) {
    $this->list[$name] = $company;
}

public function remove($name)
{
    // unset($this->list($name));
}

public function show()
{
    echo '-'.$this->company.'<br>';
    foreach ($this->list as $v) {
        echo $v->show();
    }
}

public function exec()
{
    foreach ($this->list as $v) {
        $v->exec();
    }
}
}

class HrCompany extends Company {

protected $list = array ();
public function __construct($company)
{
    $this->company = $company;
}

public function add($name,Company $company) 
{
}

public function remove($name)
{
}

public function show()
{
    echo '-'.$this->company.'<br>';
}

public function exec()
{
    echo '我是'.$this->company.',负责公司招聘'.'<br>';
}
}

class CwCompany extends Company {

protected $list = array ();
public function __construct($company)
{
    $this->company = $company;
}

public function add($name,Company $company) 
{
}

public function remove($name)
{
}

public function show()
{
    echo '-'.$this->company.'<br>';
}

public function exec()
{
    echo '我是'.$this->company.',负责公司财务'.'<br>';
}
}

客户端调用:

$company = new ConcreteCompany('总公司');
$company->add('zhr',new HrCompany('总公司hr'));
$company->add('zcw',new CwCompany('总公司财务'));

$com1 = new ConcreteCompany('分公司');
$com1->add('fhr',new HrCompany('分公司hr'));
$com1->add('fcw',new CwCompany('分公司财务'));
$company->add('fgs',$com1);

$com2 = new ConcreteCompany('分公司办事处');
$com2->add('fbhr',new HrCompany('分公司办事处hr'));
$com2->add('fbcw',new CwCompany('分公司办事处财务'));
$com1->add('fbsc',$com2);

$com3 = new ConcreteCompany('分公司1');
$com3->add('fhr1',new HrCompany('分公司1hr'));
$com3->add('fcw1',new CwCompany('分公司1财务'));
$company->add('fgs1',$com3);


$company->show();
$company->exec();

结果:

-总公司
-总公司hr
-总公司财务
-分公司
-分公司hr
-分公司财务
-分公司办事处
-分公司办事处hr
-分公司办事处财务
-分公司1
-分公司1hr
-分公司1财务
我是总公司hr,负责公司招聘
我是总公司财务,负责公司财务
我是分公司hr,负责公司招聘
我是分公司财务,负责公司财务
我是分公司办事处hr,负责公司招聘
我是分公司办事处财务,负责公司财务
我是分公司1hr,负责公司招聘
我是分公司1财务,负责公司财务