组合模式解析

组合模式:

将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。从定义中可以得到使用组合模式的环境为:在设计中想表示对象的“部分-整体”层次结构;希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。

组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。

如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。

组合模式中必须提供对子对象的管理方法,不然无法完成对子对象的添加删除等等操作,也就失去了灵活性和扩展性。但是管理方法是在Component中就声明还是在Composite中声明呢?

一种方式是在Component里面声明所有的用来管理子类对象的方法,以达到Component接口的最大化(如下图所示)。目的就是为了使客户看来在接口层次上树叶和分支没有区别——透明性。但树叶是不存在子类的,因此Component声明的一些方法对于树叶来说是不适用的。这样也就带来了一些安全性问题

另一种方式就是只在Composite里面声明所有的用来管理子类对象的方法(如下图所示)。这样就避免了

上一种方式的安全性问题,但是由于叶子和分支有不同的接口,所以又失去了透明性

    

 在这一模式中,相对于安全性,我们比较强调透明性。对于第一种方式中叶子节点内不需要的方法可以

使用空处理或者异常报告的方式来解决。

优缺点

从上面的举例中可以看到,组合模式有以下优点:

1)使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的

是单个对象还是整个组合结构,这就简化了客户端代码。

2)容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭

原则的要求,对系统的二次开发和功能扩展很有利!

当然组合模式也少不了缺点:组合模式不容易限制组合中的构件。

  1、Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,

使得客户代码可以一致的处理对象和对象容器,无需关心处理的是单个对象,还是组合的对象容器。

2、将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的

对象接口——而非对象容器的复杂内部实现结构——发生依赖关系,从而更能“应对变化”。

3、Composite模式中,是将“Add和Remove的和对象容器相关的方法”定义在“表示抽象对象的Component类”

中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔

细权衡结构,这又是必须付出的代价。

4、Composite模式在具体实现中,可以让父对象中的字对象反向追溯:如果父对象有频繁的遍历需求,可使

用缓存技巧来改善效率

class component {
     function descript(){}
     public function add(component $com){}
     public function remove(component $com){}
}
class dirComposite extends component{
    private $arrays=array();
    function descript(){
        echo "这是一枝干";
    }

    function add(component $com){

      if(in_array($com,$this->arrays,true)){
           return;
      }
         $this->arrays[]=$com;
         return count($this->arrays);
    }
    function check($a,$b){
        return( $a === $b )?0:1;
    }
    function remove(component $com){
     $this->arrays=array_udiff($this->arrays,array($com),$this->check( $a , $b ));

    }
}
class fileLeaf extends component{
   function descript(){
        echo "这是一叶枝";
    }
}
class client {
    static function main(){
        $dir=new dirComposite();
        $file1=new fileLeaf();
        $file2=new fileLeaf();
        print_r($dir->add($file1));
    }
}
client::main();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值