2013-08-06 36 views
0

我正在学习模式并在此时玩弄一个示例,但我似乎无法使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

您的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); 
+0

有道理,这个作品完美,谢谢。我甚至没有想过只使用unset() – haosmark

+0

@haosmark:你也使用'array_push'而不是'$ arr [] = $ newItem' - 我个人从未使用'array_push'。我能想到的唯一用途就是把它当作回调函数,你不能用特殊的数组语法来完成。 – Jon