php-合成模式实现

php-合成模式实现

概述

将对象组合成树形结构以表示”部分-整体”的层次结构。Composite使用户对单个对象和组合对象的使用具有一致性。
Composite变化的是一个对象的结构和组成。

这里我们还是以摩托车制造厂,由于业务发展的非常赞,一个工厂已经无法满足业务需求,经高层讨论现需要将原来的工厂按制造的摩托车款式分为两个独立工厂(跨骑摩托车厂、踏板摩托车厂)。分别位于中国的广西省和广东省。两个工厂均设立独立的财务部门,行政部门,生产部门以及后勤部门。另设立一个总部在北京。总部主要设立行政、财务、售后三个部门。由于体系的膨胀,现在的需求是针对这个场景做一套erp管理系统。能够统一分配给各分公司使用。这个需求前景下我们就可以考虑使用合成模式实现。具体实现文章后面会讲到

模式结构

建造者模式包含如下角色:

以本文实例代码为参考

  1. CompanyBase - 组合模式抽象基类
  2. Company - 公司类
  3. Administrative - 行政部门
  4. Financial - 财务部门
  5. Production - 生产部门
  6. AfterSales - 售后部门
  7. 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、使得更容易增加新类型的组件

模式的缺点

使你的设计变得更加一般化,容易增加组件也会产生一些问题,那就是很难限制组合中的组件

适用环境

1、你想表示对象的部分-整体层次结构
2、你希望用户忽略组合对象和单个对象的不同,用户将统一地使用组合结构中的所有对象。

关注微信公众号(yuantanphp)
回复关键字 设计模式 可获取以下材料
《设计模式:可复用面向对象软件的基础》pdf版.
php设计模式23种实例实现php源码
在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯伪猿

觉得文章不错?打赏支持一下吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值