组合模式
组合模式的特点: 1.所有的子类都共享一个父类。 2.你可以优化处理递归或分级数据结构。 3.用户无视对象的不同,统一的使用组合模式中的所有对象。
需求:
King: 兵种类,strength()攻击力
Swordman:剑士(兵)
Gunner:火炮手(兵)
Army:陆军(军队)
WorShip:海军(在船上剑士的攻击力下降2,火炮手攻击力下降5,一支舰队只能放5个兵)(军队)
一个军队可以增加一个兵,也可以删除一个兵,也可以增加另一个军队,形成战斗群
<?php //大父类 abstract class Kind { //集合数组 protected $_kind = array(); //添加兵种、添加陆军、添加舰队、... 添加NN public function addKind(Kind $_kind) { $this->_kind[] = $_kind; } //抽取兵种、抽取陆军、抽取舰队、... 抽取NN public function removeKind(Kind $_kind) { $this->_kind = array_udiff($this->_kind, array($_kind), create_function('$a,$b', 'return ($a === $b) ? 0:1;')); } abstract public function strength(); } ?>
<?php //火炮手 class Gunner extends Kind { public function strength() { return 28; } } ?>
<?php //剑士 class Swordman extends Kind { public function strength() { return 10; } } ?>
<?php //陆军类 class Army extends Kind { //获取陆军总攻击力 public function strength() { $_strength = 0; foreach ($this->_kind as $_kind) { //如果是士兵数组就直接遍历计算 $_strength += $_kind->strength(); //如果是部队数组,先递归回调成各自的士兵数组,再遍历计算 } return $_strength; } } ?>
<?php //舰队 class Warship extends Kind { //获取舰队总攻击力 public function strength() { $_strength = 0; foreach ($this->_kind as $_kind) { if ($_kind instanceof Swordman) $_temp = $_kind->strength() - 2; if ($_kind instanceof Gunner) $_temp = $_kind->strength() - 5; $_strength += $_temp; } return $_strength; } } ?>
$_army1 = new Army(); //创建第一支陆军部队 $_army1->addKind(new Swordman()); //添加一名剑士10 $_army1->addKind(new Swordman()); //添加一名剑士10 $_army1->addKind(new Swordman()); //添加一名剑士10 $_army1->addKind(new Gunner()); //添加一名火炮手28 echo '第一支陆军总攻击力为:'.$_army1->strength(); //总攻击力 echo '<br />'; $_army2 = new Army(); //创建第一支陆军部队 $_army2->addKind(new Swordman()); //添加一名剑士10 $_army2->addKind(new Swordman()); //添加一名剑士10 echo '第二支陆军总攻击力为:'.$_army2->strength(); //总攻击力 echo '<br />'; $_army3 = new Army(); //创建第三支部队,没有自己的士兵 $_army3->addKind($_army1); //把第一支部队组进来 $_army3->addKind($_army2); //把第二支部队组进来 echo '第三支陆军总攻击力为:'.$_army3->strength(); //总攻击力 echo '<br />'; $_warship1 = new Warship(); $_warship1->addKind(new Swordman()); $_warship1->addKind(new Swordman()); $_warship1->addKind(new Swordman()); $_warship1->addKind(new Swordman()); echo '第一支海军舰队的总攻击力为:'.$_warship1->strength(); echo '<br />'; $_xxx = new Army(); $_xxx->addKind($_army3); $_xxx->addKind($_warship1); $_xxx->addKind(new Gunner()); echo '第一支陆军+海军舰队混合战队的总攻击力为:'.$_xxx->strength();