php-合成模式实现
概述
将对象组合成树形结构以表示”部分-整体”的层次结构。Composite使用户对单个对象和组合对象的使用具有一致性。 Composite变化的是一个对象的结构和组成。
这里我们还是以摩托车制造厂,由于业务发展的非常赞,一个工厂已经无法满足业务需求,经高层讨论现需要将原来的工厂按制造的摩托车款式分为两个独立工厂(跨骑摩托车厂、踏板摩托车厂)。分别位于中国的广西省和广东省。两个工厂均设立独立的财务部门,行政部门,生产部门以及后勤部门。另设立一个总部在北京。总部主要设立行政、财务、售后三个部门。由于体系的膨胀,现在的需求是针对这个场景做一套erp管理系统。能够统一分配给各分公司使用。这个需求前景下我们就可以考虑使用合成模式实现。具体实现文章后面会讲到
模式结构
建造者模式包含如下角色:
以本文实例代码为参考
- CompanyBase - 组合模式抽象基类
- Company - 公司类
- Administrative - 行政部门
- Financial - 财务部门
- Production - 生产部门
- AfterSales - 售后部门
- Logistics - 后勤部门
图例
代码实例
<?php
abstract class CompanyBase{
protected $name;
public function __construct($name){
$this->name = $name;
}
public function getName(){
return $this->name;
}
abstract function add(CompanyBase $c);
abstract function remove(CompanyBase $c);
abstract function show($deep);
abstract function work($deep);
}
class Company extends CompanyBase{
protected $item = [];
public function add(CompanyBase $c){
$nodeName = $c->getName();
if(!isset( $this->item[$nodeName] )){
$this->item[$nodeName] = $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 "<br>";
foreach($this->item as $value){
$value->show($deep+4);
}
}
public function work($deep = 0){
foreach($this->item as $value){
echo str_repeat("?",$deep)."[{$this->name}]<br>";
$value->work($deep+2);
}
}
}
class Administrative 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 "<br>";
}
public function work($deep = 0){
echo str_repeat("?",$deep)."行政部门主要负责公司文书以及附带人力资源及相关培训";
echo "<br>";
}
}
class Financial 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 "<br>";
}
public function work($deep = 0){
echo str_repeat("?",$deep)."财务部门主要负责公司财务";
echo "<br>";
}
}
class Production 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 "<br>";
}
public function work($deep = 0){
echo str_repeat("?",$deep)."生产部门主要负责生产组装摩托";
echo "<br>";
}
}
class AfterSales 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 "<br>";
}
public function work($deep = 0){
echo str_repeat("?",$deep)."售后部门主要负责公司产品售后咨询对接";
echo "<br>";
}
}
class Logistics 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 "<br>";
}
public function work($deep = 0){
echo str_repeat("?",$deep)."后勤部门为公司提供后勤服务";
echo "<br>";
}
}
$administrative = new Administrative("行政部门");
$financial = new Financial("财务部门");
$production = new Production("生产部门");
$logistics = new Logistics("后勤部门");
$afterSales = new AfterSales("售后部门");
$companyBj = new Company("北京摩托公司");
$companyBj->add($administrative);
$companyBj->add($financial);
$companyBj->add($afterSales);
$companyGx = new Company("广西摩托分公司");
$companyGx->add($administrative);
$companyGx->add($financial);
$companyGx->add($production);
$companyGx->add($logistics);
$companyBj->add($companyGx);
$companyGd = new Company("广东摩托分公司");
$companyGd->add($administrative);
$companyGd->add($financial);
$companyGd->add($production);
$companyGd->add($logistics);
$companyBj->add($companyGd);
$companyBj->show();
$companyBj->work();
模式分析
- 必须存在不可分割基本元素;
- 组合后的物体任然可以被组合。
模式优缺点
模式的优点 1、简化客户代码 2、使得更容易增加新类型的组件
模式的缺点
使你的设计变得更加一般化,容易增加组件也会产生一些问题,那就是很难限制组合中的组件
适用环境
1、你想表示对象的部分-整体层次结构 2、你希望用户忽略组合对象和单个对象的不同,用户将统一地使用组合结构中的所有对象。
获取更多学习资源请关注微信公众号:yuantanphp
|