将一组对象组合为可以像单个对象一样被使用的结构
<?php
//战斗单位类
/* abstract class Unit{
//抽象的攻击强度方法
abstract function bombardStrength();
} */
/* 战斗单位类
* abstract class Unit{
abstract function addUnit(Unit $unit);
abstract function removeUnit(Unit $unit);
abstract function bombardStrength();
} */
//战斗单位类
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){
$units=array();
foreach ($this->units as $thisunit){
if(!unit!==$thisunit){
$units[]=$thisunit;
}
}
$this->units=$units;
}
function addUnit(Unit $unit){
if(in_array($unit, $this->units,true)){
return;
}
$this->units[]=$unit;
}
}
//弓箭手类
/* class Archer extends Unit{
//实现父类的抽象方法 攻击强度
function bombardStrength(){
return 4;
}
} */
//弓箭手
class Archer extends Unit{
function addUnit(Unit $unit){
throw new UnitException(get_class($this)."is a leaf");
}
function removeUnit(Unit $unit){
throw new UnitException(get_class($this)."is a leaf");
}
function bombardStrength(){
return 4;
}
}
//激光炮单位
class LaserCanonUnit extends Unit{
function bombardStrength(){
return 44;
}
function addUnit(Unit $unit){
}
function removeUnit(Unit $unit){
}
}
//陆军类
/* class Army{
private $units=array();
private $armies=array();
//添加单位
function addUnit(Unit $unit){
array_push($this->units, $unit);
}
//攻击强度
function bombardStrength(){
$ret=0;
foreach ($this->units as $unit){
$ret+=$unit->bombardStrength();
}
foreach ($this->armies as $army){
$ret+=$army->bombardStrength();
}
return $ret;
}
//添加陆军
function addArmy(Army $army){
array_push($this->armies, $army);
}
} */
class Army extends Unit{
public $units=array();
//添加单位
function addUnit(Unit $unit){
if(in_array($unit, $this->units,true)){
return;
}
$this->units[]=$unit;
}
//移除单位
function removeUnit(Unit $unit){
$units=array();
foreach ($this->units as $thisunit){
if($unit!==$thisunit){
$units[]=$thisunit;
}
}
$this->units=$thisunit;
}
//攻击强度
function bombardStrength(){
$ret=0;
foreach ($this->units as $unit){
$ret+=$unit->bombardStrength();
}
return $ret;
}
//添加陆军
function addArmy(Army $army){
array_push($this->armies, $army);
}
}
//运兵船
class TroopCarrier{
function addUnit(Unit $unit){
if($unit instanceof Cavalry){//骑兵对象
throw new UnitException("Can't get a horse on the vehicle");
}
super::addUnit($unit);
}
function bombardStrength(){
return 0;
}
}
//骑兵对象
class Cavalry extends CompositeUnit{
function addUnit(Unit $unit){
}
function removeUnit(Unit $unit){
}
function bombardStrength(){
}
}
class UnitException extends Exception{
}
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;
}
}
$main_army=new Army();
$main_army->addUnit(new Archer());
$main_army->addUnit(new LaserCanonUnit());
$sub_army=new Army();
$sub_army->addUnit(new Archer());
$sub_army->addUnit(new Archer());
$sub_army->addUnit(new Archer());
$main_army->addUnit($sub_army);
// print_r($main_army->units);
// print "攻击强度:{$main_army->bombardStrength()}<br>";
UnitScript::joinExisting($main_army, $sub_army);