设计模式专题(十五) ——组合模式

设计模式专题(十五)——组合模式

(原创内容,转载请注明来源,谢谢)

一、概述

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

使用组合模式,会使类之间完全透明,每个类都具有同样的方法,当又能区分谁是父类、谁是子类,实现一个树状的类图。当希望可以忽略单个对象和组合对象的区别,就可以使用此方法来管理对象。

二、优点

组合模式包含基本对象和组合对象的层次结构,使得客户端可以统一使用组合结构和对象。

三、类图

使用组合模式后,各类的层次结构如下:

四、设计实现

1、父类Component

         abstractclass Component{
                   private$arrChilds;
                   private$parent;
                   private$name;
                   publicfunction __construct($name, Component $co = null){
         $this->parent =$co;
         $this->name =$name;
}
public function getName();//获取该节点的名字
         public function remove($name){}//移除节点
         public function add(Component $co){}//增加节点
         public function getChilds(){}//获取全部孩子节点
         public function getParents{}//获取全部父节点
         public function specificMethods($prop1=null,$prop2=null){}//每个类特定的操作
}

2、子节点类Composite

class Compositeextends Component{
         private $arrChilds;
         private $parent;
         private $name;
         public function __construct($name,Component $co){
                   $this->parent = $co;
                   $this->name = $name;
                   $this->arrChilds =array();
         }
         //根据名字删除子节点,该删除仅删除子节点和父节点的联系,并不会从内存中删除子节点
         public function remove($name){
                   $res = false;
                   if(empty($this->arrChilds)){
                            return $res;
                   }
                   $arr = $this->arrChilds;
                   for($i=;$i<count($arr);$i++){
                            if($name ==$arr[$i]->name){
                                     unset($this->arrChilds{$i});
                                     $res =true;
                                     break;
                            }
                   }
                   return $res;
         }
         //添加子节点
         public function add(Component $co){
                   array_push($this->arrChilds,$co);
         }
         //获取全部孩子节点,引用传递获取值
         public function getChilds(array&$res){
                   foreach($this->arrChildsas $child){
                            array_push($res,$child);
                            if(null !=$child->arrChilds && !empty($child->arrChilds)){
                                     $child->getChilds($res);//递归
                            }
                   }
                   return $res;
         }
         //获取父节点
         public function getParents(array&$res){
                   array_push($res,$this->parent);
                   if(null != $this->parent->parent&& !empty($this->parent->parent)){
                            $this->parent->getParents($res);
                   }
                   return $res;
         }
         //独特的方法
         public functionspecificMethods($prop1=null,$prop2=null){
                   //......
         }
}

3、叶子节点类

class Leafextends Component{
         private $arrChilds;
         private $parent;
         private $name;
         public function __construct($name,Component $co){
                   $this->parent = $co;
                   $this->name = $name;
                   $this->arrChilds = null;
         }       
         public function remove($name = null){
                   return null;
         }
         public function add(Component $co =null){
                   return null;
         }
         public function getChilds(array&$res = null){
                   return null;
         }
         //获取父节点
         public function getParents(array&$res){
                   array_push($res,$this->parent);
                   if(null !=$this->parent->parent && !empty($this->parent->parent)){
                            $this->parent->getParents($res);
                   }
                   return $res;
         }
         //独特的方法
         public functionspecificMethods($prop1=null,$prop2=null){
                   //......
         }       
}

——written by linhxx 2017.08.11

相关阅读:

设计模式专题(十四)——适配器模式

设计模式专题(十三) ——备忘录模式

设计模式专题(十二)——状态模式

设计模式专题(十一)——抽象工厂模式

设计模式专题(十)——观察者模式

设计模式专题(九) ——外观模式

设计模式专题(八) ——模板方法模式

设计模式专题(七)——建造者模式

设计模式专题(六)——原型模式

设计模式专题(五)——工厂方法模式

设计模式专题(四)——代理模式

设计模式专题(三)——装饰模式

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

C/C++练习题(三)

分析:在我们看来,虽然使用字符数组和字符指针差不多,printf都可以打印出字符串出来,但是编译器对他们的处理完全不同。 对于字符指针,编译器看到后,...

4894
来自专栏Python小屋

暴力测试也疯狂——论Python代码优化

问题描述:在123456789这9个数字中间插入任意多个+和-的组合,使得表达式的值为100,输出所有符合条件的表达式。 对于该问题,前天推送了一个暴力测试的代...

3344
来自专栏noteless

[十三]JavaIO之PushBackInputStream

看得出来,如果你从来不曾回退过,那么好像什么都一样,还是使用原来的InputStream 进行读取

1512
来自专栏章鱼的慢慢技术路

Go语言相关练习_选择题(2)

go语言中字符串是UTF-8编码并存储的,它语言不定长的字节,所以它不支持下标操作,因为没一个下标操作代表的是固定长度的字节,所以不能对字符串中某个字符单独赋值...

902
来自专栏玄魂工作室

看代码学安全(11) - unserialize反序列化漏洞

大家好,我们是红日安全-代码审计小组。最近我们小组正在做一个PHP代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫 PHP-Audit-Labs 。...

1093
来自专栏每日一篇技术文章

Swift3.0 - 异常错误

711
来自专栏V站

如何提高PHP编程效率,提升程序编译质量(53条)

用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串...

1555
来自专栏林德熙的博客

dotnet core 编程规范

本文实际只是翻译 .NET Core foundational libraries 官方文档的编码风格。

772
来自专栏企鹅号快讯

PHP中被忽略的性能优化利器:生成器

如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生。但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP5.5.0才引入的功能,也...

38014
来自专栏MyBlog

Effective Java 读书笔记(7)避免finalizer

对于Finalizers他们的使用可能会造成错误的产生,糟糕的性能以及移植性的问题,当然Finalizers有着一些有用的优点,我们会在后续介绍这些,但是作为首...

1002

扫码关注云+社区