面向对象的洗礼:设计模式(十九)之组合模式
组合模式告诉我们,对待部分和对待整体是一样的。整体和部分就是总部和分部的关系。使用设计模式中的组合模式,客户端不需要知道它调用的到底是整体的接口还是部分的接口。北京总公司为整体,下属有上海分公司,北京总公司财务,北京总公司人事。上海分公司下属有上海分公司财务,上海分公司财务。这就是整体与部分的关系,是组合模式的使用前提。需求中是体现部分和整体的结构时,用户不需要关心是在使用整体的对象还是单个对象而是使用统一的接口对象时,就可以考虑设计模式中的组合模式了。
组合模式:可以用整体-部分的结构来表示一个对象的结构层次。使用组合模式使得用户对组合对象和单个对象没有不同的感受。
场景:北京总公司,上海分公司,北京财务部,上海财务部的公司结构。以PHP为代码环境。代码仅仅为了说明组合模式,并不推荐实际开发中的使用。
<?php //具体的公司 class ConcreteCompany{ public $name; private $companyList = array(); public function __construct($name){ $this->name = $name; } public function add($obj){ $this->companyList[] = $obj; } public function display(){ foreach($this->companyList as $company){ echo '--'; echo $company->name; echo '<br>'; if(!empty($company->companyList)){ echo '--'; $company->display(); } } } } class Department{ public $name; public function __construct($name){ $this->name = $name; } public function add(){ echo '已经是最小分类了,不能再细分了<br>'; } public function display(){ echo '--'; echo $this->name; echo '<br>'; } } //客户端/接口 $headCompany = new ConcreteCompany('北京总公司'); $headCompany->add(new Department('北京总公司财务部')); $headCompany->add(new Department('北京总公司人事部')); $concreteCompany1 = new ConcreteCompany('上海分公司'); $concreteCompany1->add(new Department('上海分公司财务部')); $concreteCompany1->add(new Department('上海分公司人事部')); $headCompany->add($concreteCompany1); $concreteCompany2 = new ConcreteCompany('青岛分公司'); $concreteCompany2->add(new Department('青岛分公司财务部')); $concreteCompany2->add(new Department('青岛分公司人事部')); $headCompany->add($concreteCompany2); echo '全公司组织架构:<br>'; $headCompany->display(); echo '<br><br>上海分公司组织架构:<br>'; $concreteCompany1->display(); echo '<br><br>上海分公司组织架构:<br>'; $concreteCompany2->display();