让面向对象编程更加灵活的的模式-----组合模式
uml
代码实现
<?php /* combine.php 组合模式 */ abstract class Unit{ function getComposite(){ return null; } abstract function bombardStrengrg(); } abstract class CompositeUnit extends Unit{ private $unit = array(); function getComposite(){ return $this; } protected function units(){ return $this->units; } function removeUnit(Unit $unit){ $this->unit = array_udiff($this->unit,array($unit), function($a,$b){return ($a===$b)?0:1;}); } function addUnit(Unit $unit){ if(in_array($unit,$this->unit,true)){ return; } $this->unit[] = $unit; } } class Army extends CompositeUnit{ function bombardStrengrg(){ $ret = 0; foreach ($this->unit as $unit) { $ret+=$unit->bombardStrengrg(); } return $ret; } } class UnitException extends Exception{} class Archer extends Unit{ function bombardStrengrg(){ return 4; } } class LaserCanon extends Unit{ function bombardStrengrg(){ return 5; } } //client 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; } } ?>
效果
组合模式的简化有时会降低对象类型的安全为代价,模型变得越复杂,就不得不手动进行越多的类型检查
组合模式的操作成本很大,解决办法是在父级对象中缓存计算结果,使接下来的调用减少系统开销
在对象持久化上,虽然组合模式是一个优雅的模式,但是他并不能将自身轻松的存储到关系型数据库里,适合于持久化为xml
小结
因为组合模式是树形结构,所以对整体的操作会影响到局部,而通过组合,对调用端来说局部的数据又是透明的,组合模式让这些操作和查询对调用端透明,对象数可以方便进行遍历,你也可以轻松的在组合结构中加入新的组件类型,另一方面,组合模式依赖于其组成部分的简单性