我正在研究模式并且正在玩一个示例,但是我似乎无法使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.这里有什么问题?有没有更好的方法从数组中删除元素?
答案 0 :(得分:1)
您的array_splice
调用错误,因为省略$length
参数会删除从该点到数组末尾的所有内容。它应该是:
array_splice($this->_units, $key, 1);
那就是说,我不确定为什么你首先要保留数字索引 - 使用unset($this->_units[$key])
也可以做到这一点而没有任何明显的副作用。
最后,独立完成in_array
和array_search
毫无意义。您可以像这样重写代码:
$key = array_search($unit, $this->_units);
if ($key === false) {
// exception
}
array_splice($this->_units, $key, 1);