• PHP组合模式


    一、组合模式简述

    1.组合定义了一个单根继承体系,使具有不同职责的集合可以并肩工作

    2.如果想像对待单个对象一样对待组合对象,那么组合模式十分有用

    3.组合模式不能很好地在关系数据库中保存数据,但却非常适用于xml的持久化,这是因为xml元素通常是由树型结构的子元素组合而成的。

    4.组全模式需要注意操作的成本 ,组合的方法可能会逐级调用对象树中下级分支的方法,如果一个对象树中有大量的子对象,一个简单的调用可能人导致系统崩溃(递归)

    二、组合例子

    1.简述:要写一些类实现计算部队战斗力,部队内可能有没的军种,不同的军种有不同的战斗力,每个军种由士兵或类似的基本单元构成,一个部队可以合并另一个部队,但一个士兵或基本单元不可以合并另一个士兵或基本单元

    2.类图:

    三、代码

    <?php
    
    abstract class Unit {
        function getComposite() {
            return null;
        }
    
        abstract function bombardStrength();
    }
    
    
    abstract class CompositeUnit extends Unit {
        private $units = array();
    
        function getComposite() {
            return $this;
        }
    
        protected function units() {
            return $this->units;
        }
    
        function removeUnit( Unit $unit ) {
            // >= php 5.3
            //$this->units = array_udiff( $this->units, array( $unit ), 
            //                function( $a, $b ) { return ($a === $b)?0:1; } );
    
            // < php 5.3
            $this->units = array_udiff( $this->units, array( $unit ), 
                            create_function( '$a,$b', 'return ($a === $b)?0:1;' ) );
        }
    
        function addUnit( Unit $unit ) {
            if ( in_array( $unit, $this->units, true ) ) {
                return;
            }
            $this->units[] = $unit;
        }
    }
    class Army extends CompositeUnit {
    
        function bombardStrength() {
            $ret = 0;
            foreach( $this->units as $unit ) {
                $ret += $unit->bombardStrength();
            }
            return $ret;
        }
    
    }
    
    class Archer extends Unit {
        function bombardStrength() {
            return 4;
        }
    }
    
    class LaserCannonUnit extends Unit {
        function bombardStrength() {
            return 44;
        }
    }
    
    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;
        }
    }
    
    $army1 = new Army();
    $army1->addUnit( new Archer() );
    $army1->addUnit( new Archer() );
    
    $army2 = new Army();
    $army2->addUnit( new Archer() );
    $army2->addUnit( new Archer() );
    $army2->addUnit( new LaserCannonUnit() );
    
    $composite = UnitScript::joinExisting( $army2, $army1 );
    print_r( $composite );
    
    ?>

    运行结果:

    Army Object ( [units:CompositeUnit:private] => Array ( [0] => Archer Object ( ) [1] => Archer Object ( ) [2] => Army Object ( [units:CompositeUnit:private] => Array ( [0] => Archer Object ( ) [1] => Archer Object ( ) [2] => LaserCannonUnit Object ( ) ) ) ) )
  • 相关阅读:
    数学 之 hdu 4722
    DP + math 之 Codeforces 126D
    计算几何 之 hdu 1077 poj 1981 O(n^2logn)
    计算几何 之 hdu 1077 poj 1981 O(n^3)
    字典树 之 hdu 1800
    字典树 之 poj 1056
    字典树 之 hdu 4099
    字典树 之 hdu 1247
    解决java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date
    显示Mac壁纸所在路径以及接下来的事情你懂得
  • 原文地址:https://www.cnblogs.com/shamgod/p/5018000.html
Copyright © 2020-2023  润新知