zoukankan      html  css  js  c++  java
  • PHP设计模式之组合模式

      当我们的一个对象可能代表一个单一的实体,或者一个组合的实体,但是仍然需要通过同样的方式被使用时,这种情形则适合使用组合模式的设计。

      组合模式是一种结构型模式。

      当看了书上的解释之后,并不是很理解,遂去翻了翻《大化设计模式》,以下为原文截图:

      看完这本书上的解释之后也不是很理解,但是能够进行编码了,以下为组合模式的代码:

    <?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("&emsp;",$deep)."[{$this->name}]<br>";
                $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 "<br>";
    
        }
        public function work($deep = 0){
    
            echo str_repeat("&emsp;",$deep)."人力资源部门的工作是为公司招聘人才";
            echo "<br>";
        }
    
    }
    
    /**
     * 商务部门
     */
    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 "<br>";
    
        }
        public function work($deep = 0){
    
            echo str_repeat("&emsp;",$deep)."商务部门的工作是为公司赚取利润";
            echo "<br>";
        }
    }

       设计好类之后,就可以使用它了:

    $c = new Company("北京某科技公司");
    $h = new HumanResources("人力资源部门");
    $com = new Commerce("商务部门");
    $c->add($h);
    $c->add($com);
    
    //天津分公司
    //为了偷懒,分公司的部门直接copy母公司的
    $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. 组合后的物体任然可以被组合。
  • 相关阅读:
    hash表及带注释插头dp
    NOIP模拟测试9「随·单·题」
    静态点分治总结
    NOIP模拟测试8「匹配·回家」
    NOIP模拟测试8「寿司」
    「PKUWC2018」Slay the Spire
    矩阵快速幂总结
    SQL中的object_id函数
    SQL数据库Replace的用法
    SQL批量提交修改业务
  • 原文地址:https://www.cnblogs.com/praglody/p/6783317.html
Copyright © 2011-2022 走看看