让面向对象编程更加灵活的的模式-----组合模式

 uml

代码实现

<?php
/*
combine.php
组合模式
*/

abstract class Unit{
    function getComposite(){
        return null;
    }
    abstract function bombardStrengrg();
}

abstract class CompositeUnit extends Unit{
    private $unit = array();

    function getComposite(){
        return $this;
    }

    protected function units(){
        return $this->units;
    }

    function removeUnit(Unit $unit){
        $this->unit = array_udiff($this->unit,array($unit),
            function($a,$b){return ($a===$b)?0:1;});
    }

    function addUnit(Unit $unit){
        if(in_array($unit,$this->unit,true)){
            return;
        }
        $this->unit[] = $unit;
    }
}

class Army extends CompositeUnit{
    function bombardStrengrg(){
        $ret = 0;
        foreach ($this->unit as $unit) {
            $ret+=$unit->bombardStrengrg();
        }
        return $ret;
    }
}


class UnitException extends Exception{}

class Archer extends Unit{
    function bombardStrengrg(){
        return 4;
    }
}

class LaserCanon extends Unit{
    function bombardStrengrg(){
        return 5;
    }
}

//client
class UnitScript{
    //新来者,原来占据者
    static function joinExisting(Unit $newUnit,Unit $occupyingUnit){
        $comp;
        //判断是局部对象还是组合对象
        if(!is_null($comp = $occupyingUnit->getComposite())){
            $comp->addUnit($newUnit);
        }else{
            $comp = new Army();
            $comp->addUnit($occupyingUnit);
            $comp->addUnit($newUnit);
        }
        return $comp;
    }
}
?>

 

效果

组合模式的简化有时会降低对象类型的安全为代价,模型变得越复杂,就不得不手动进行越多的类型检查

组合模式的操作成本很大,解决办法是在父级对象中缓存计算结果,使接下来的调用减少系统开销

在对象持久化上,虽然组合模式是一个优雅的模式,但是他并不能将自身轻松的存储到关系型数据库里,适合于持久化为xml

 

小结

因为组合模式是树形结构,所以对整体的操作会影响到局部,而通过组合,对调用端来说局部的数据又是透明的,组合模式让这些操作和查询对调用端透明,对象数可以方便进行遍历,你也可以轻松的在组合结构中加入新的组件类型,另一方面,组合模式依赖于其组成部分的简单性

 

posted @ 2016-11-15 11:32  rcj_飞翔  阅读(237)  评论(0编辑  收藏  举报