从复合/数组中删除元素(复合模式)

时间:2013-08-06 16:29:50

标签: php

我正在研究模式并且正在玩一个示例,但是我似乎无法使removeUnit方法按预期工作。这是代码:

 <?php
abstract class Unit
{
    abstract function strength();
    public function getComposite()
    {
        return false;
    }
}

/*
 * composite / group class
 */
abstract class Composite extends Unit
{
    private $_units = array();

    // check if class is a composite or not
    public function getComposite()
    {
        return true;
    }

    public function getUnits()
    {
        return $this->_units;
    }

    // add a unit to the group
    public function addUnit(Unit $unit)
    {
        if( in_array($unit, $this->_units, true) ) {
            Throw new exception("Sorry, the following unit is already in the army");
        } else {
            array_push($this->_units, $unit);
        }
    }

    //remove a unit from the group
    public function removeUnit(Unit $unit)
    {
        if( ! in_array($unit, $this->_units, true) ) {
            Throw new Exception("Hm, it looks like this unit is not a part of this army.");
        } else {
            $key = array_search($unit, $this->_units);
            array_splice($this->_units, $key);
        }
    }
}

class Army extends Composite
{
    public function strength()
    {
        $units = $this->getUnits();
        $armyStrength = 0;
        foreach( $units as $unit ) {
            $armyStrength += $unit->strength();
        }
        return $armyStrength;
    }
}

class Riffle extends Unit
{
    public function strength()
    {
        return 5;
    }
}

class Rocket extends Unit
{
    public function strength()
    {
        return 15;
    }
}

$riffle1 = new Riffle();
$riffle2 = new Riffle();
$riffle3 = new Riffle();

$rocket1 = new Rocket();
$rocket2 = new Rocket();
$rocket3 = new Rocket();

$squad = new Army();

$squad->addUnit($riffle1);
$squad->addUnit($riffle2);
$squad->addUnit($rocket1);
$squad->removeUnit($riffle2);
echo $squad->strength();

问题在于:

//remove a unit from the group
public function removeUnit(Unit $unit)
{
    if( ! in_array($unit, $this->_units, true) ) {
        Throw new Exception("Hm, it looks like this unit is not a part of this army.");
    } else {
        $key = array_search($unit, $this->_units);
        array_splice($this->_units, $key);
    }
}

如果我删除recket1,一切正常,但如果我尝试删除riffle1或2,那么我的力量会返回0.这里有什么问题?有没有更好的方法从数组中删除元素?

1 个答案:

答案 0 :(得分:1)

您的array_splice调用错误,因为省略$length参数会删除从该点到数组末尾的所有内容。它应该是:

array_splice($this->_units, $key, 1);

那就是说,我不确定为什么你首先要保留数字索引 - 使用unset($this->_units[$key])也可以做到这一点而没有任何明显的副作用。

最后,独立完成in_arrayarray_search毫无意义。您可以像这样重写代码:

$key = array_search($unit, $this->_units);
if ($key === false) {
    // exception
}

array_splice($this->_units, $key, 1);