千家信息网

PHP中组合模式与装饰模式的示例分析

发表于:2026-10-30 作者:千家信息网编辑
千家信息网最后更新 2026年10月30日,这篇文章将为大家详细讲解有关PHP中组合模式与装饰模式的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:组合模式定义:组合模式定义了一个单根继承体系
千家信息网最后更新 2026年10月30日PHP中组合模式与装饰模式的示例分析

这篇文章将为大家详细讲解有关PHP中组合模式与装饰模式的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

具体如下:

组合模式

定义:组合模式定义了一个单根继承体系,使具有截然不同职责的集合可以并肩工作。

一个军队的案例,

军队整合成员,输出火力

units, $unit );  }  function bombardStrength() { // 火力    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    return $ret;  }}$unit1 = new Archer();$unit2 = new LaserCannonUnit();$army = new Army();$army->addUnit( $unit1 );$army->addUnit( $unit2 );print $army->bombardStrength(); // 输出火力?>

output:
48
军队进一步整合其他军队

units, $unit );  }  function addArmy( Army $army ) {    array_push( $this->armies, $army );  }  function bombardStrength() {    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    foreach( $this->armies as $army ) {      $ret += $army->bombardStrength();    }    return $ret;  }}$unit1 = new Archer();$unit2 = new LaserCannonUnit();$army = new Army();$army->addUnit( $unit1 );$army->addUnit( $unit2 );print $army->bombardStrength();print "\n";$army2 = clone $army; // 克隆军队$army->addArmy( $army2 );print $army->bombardStrength();print "\n";?>

output:
48
96

更好的方式,支持新增,移除等等其他功能。

units, true ) ) { // $this用于调用正常的属性或方法,self调用静态的方法,属性或者常量      return;    }    $this->units[] = $unit;  }  function removeUnit( Unit $unit ) {    // >= php 5.3    $this->units = array_udiff( $this->units, array( $unit ),            function( $a, $b ) { return ($a === $b)?0:1; } );    // < php 5.3    // $this->units = array_udiff( $this->units, array( $unit ),    //        create_function( '$a,$b', 'return ($a === $b)?0:1;' ) );    // 对象数组,create_function,创建函数  }  function bombardStrength() {    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    return $ret;  }}// quick example classesclass Tank extends Unit { // 坦克  function addUnit( Unit $unit ) {}  function removeUnit( Unit $unit ) {}  function bombardStrength() {    return 4;  }}class Soldier extends Unit { // 士兵  function addUnit( Unit $unit ) {}  function removeUnit( Unit $unit ) {}  function bombardStrength() {    return 8;  }}$tank = new Tank();$tank2 = new Tank();$soldier = new Soldier();$army = new Army();$army->addUnit( $soldier );$army->addUnit( $tank );$army->addUnit( $tank2 );print_r( $army );print $army->bombardStrength()."\n";$army->removeUnit( $soldier );print_r( $army );print $army->bombardStrength()."\n";?>

output:

Army Object(  [units:Army:private] => Array    (      [0] => Soldier Object        (        )      [1] => Tank Object        (        )      [2] => Tank Object        (        )    ))16Army Object(  [units:Army:private] => Array    (      [1] => Tank Object        (        )      [2] => Tank Object        (        )    ))8

添加异常处理

units, true ) ) {      return;    }    $this->units[] = $unit;  }  function removeUnit( Unit $unit ) {    // >= php 5.3    //$this->units = array_udiff( $this->units, array( $unit ),    //        function( $a, $b ) { return ($a === $b)?0:1; } );    // < php 5.3    $this->units = array_udiff( $this->units, array( $unit ),            create_function( '$a,$b', 'return ($a === $b)?0:1;' ) );  }  function bombardStrength() {    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    return $ret;  }}class UnitException extends Exception {}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;  }}$archer = new Archer();$archer2 = new Archer();$archer->addUnit( $archer2 );?>

output:

Fatal error: Uncaught exception 'UnitException' with message 'Archer is a leaf'

点评:组合模式中的一切类都共享同一个父类型,可以轻松地在设计中添加新的组合对象或局部对象,而无需大范围地修改代码。

最终的效果,逐步优化(完美):

units, true ) ) {      return;    }    $this->units[] = $unit;  }  function removeUnit( Unit $unit ) {    // >= php 5.3    //$this->units = array_udiff( $this->units, array( $unit ),    //        function( $a, $b ) { return ($a === $b)?0:1; } );    // < php 5.3    $this->units = array_udiff( $this->units, array( $unit ),            create_function( '$a,$b', 'return ($a === $b)?0:1;' ) );  }  function bombardStrength() {    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    return $ret;  }}// create an army$main_army = new Army();// add some units$main_army->addUnit( new Archer() );$main_army->addUnit( new LaserCannonUnit() );// create a new army$sub_army = new Army();// add some units$sub_army->addUnit( new Archer() );$sub_army->addUnit( new Archer() );$sub_army->addUnit( new Archer() );// add the second army to the first$main_army->addUnit( $sub_army );// all the calculations handled behind the scenesprint "attacking with strength: {$main_army->bombardStrength()}\n";?>

output:

attacking with strength: 60

更牛逼的组合处理,

units;  }  function removeUnit( Unit $unit ) {    // >= php 5.3    //$this->units = array_udiff( $this->units, array( $unit ),    //        function( $a, $b ) { return ($a === $b)?0:1; } );    // < php 5.3    $this->units = array_udiff( $this->units, array( $unit ),            create_function( '$a,$b', 'return ($a === $b)?0:1;' ) );  }  function addUnit( Unit $unit ) {    if ( in_array( $unit, $this->units, true ) ) {      return;    }    $this->units[] = $unit;  }}class Army extends CompositeUnit {  function bombardStrength() {    $ret = 0;    foreach( $this->units as $unit ) {      $ret += $unit->bombardStrength();    }    return $ret;  }}class Archer extends Unit {  function bombardStrength() {    return 4;  }}class LaserCannonUnit extends Unit {  function bombardStrength() {    return 44;  }}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;  }}$army1 = new Army();$army1->addUnit( new Archer() );$army1->addUnit( new Archer() );$army2 = new Army();$army2->addUnit( new Archer() );$army2->addUnit( new Archer() );$army2->addUnit( new LaserCannonUnit() );$composite = UnitScript::joinExisting( $army2, $army1 );print_r( $composite );?>

output:

Army Object(  [units:CompositeUnit:private] => Array    (      [0] => Archer Object        (        )      [1] => Archer Object        (        )      [2] => Army Object        (          [units:CompositeUnit:private] => Array            (              [0] => Archer Object                (                )              [1] => Archer Object                (                )              [2] => LaserCannonUnit Object                (                )            )        )    ))

点评:Unit 基础,CompositeUnit复合中实现add与remove。军队继承Composite,射手继承Archer。这样射手中就不会有多余的add与remove方法了。

装饰模式

装饰模式帮助我们改变具体组件的功能。

看例子

wealthfactor;  }}class DiamondPlains extends Plains { // 钻石地段  function getWealthFactor() {    return parent::getWealthFactor() + 2;  }}class PollutedPlains extends Plains { // 污染地段  function getWealthFactor() {    return parent::getWealthFactor() - 4;  }}$tile = new PollutedPlains();print $tile->getWealthFactor();?>

output:
-2

点评:不具有灵活性,我们不能同时获得钻石与被污染的土地的资金情况。

装饰模式使用组合和委托而不是只使用继承来解决功能变化的问题。

看例子:

wealthfactor;  }}abstract class TileDecorator extends Tile { // 装饰  protected $tile;  function __construct( Tile $tile ) {    $this->tile = $tile;  }}class DiamondDecorator extends TileDecorator { // 钻石装饰  function getWealthFactor() {    return $this->tile->getWealthFactor()+2;  }}class PollutionDecorator extends TileDecorator { // 污染装饰  function getWealthFactor() {    return $this->tile->getWealthFactor()-4;  }}$tile = new Plains();print $tile->getWealthFactor(); // 2$tile = new DiamondDecorator( new Plains() );print $tile->getWealthFactor(); // 4$tile = new PollutionDecorator(       new DiamondDecorator( new Plains() ));print $tile->getWealthFactor(); // 0?>

output:
2
4
0

点评:这个模型具有扩展性。我们不需要创建DiamondPollutionPlains对象就可以构建一个钻石被污染的对象。

一个更逼真的例子

processrequest = $pr;  }}class LogRequest extends DecorateProcess { // 日志请求  function process( RequestHelper $req ) {    print __CLASS__.": logging request\n"; // 当前类,有点递归的感觉    $this->processrequest->process( $req );  }}class AuthenticateRequest extends DecorateProcess { // 认证请求  function process( RequestHelper $req ) {    print __CLASS__.": authenticating request\n";    $this->processrequest->process( $req );  }}class StructureRequest extends DecorateProcess { // 组织结构请求  function process( RequestHelper $req ) {    print __CLASS__.": structuring request\n";    $this->processrequest->process( $req );  }}$process = new AuthenticateRequest( new StructureRequest(                  new LogRequest (                  new MainProcess()                  ))); // 这样可以很灵活的组合进程的关系,省去很多重复的继承$process->process( new RequestHelper() );print_r($process);?>

output:

AuthenticateRequest: authenticating requestStructureRequest: structuring requestLogRequest: logging requestMainProcess: doing something useful with requestAuthenticateRequest Object(  [processrequest:protected] => StructureRequest Object    (      [processrequest:protected] => LogRequest Object        (          [processrequest:protected] => MainProcess Object            (            )        )    ))

关于"PHP中组合模式与装饰模式的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

模式 组合 军队 对象 方法 钻石 处理 污染 例子 功能 火力 篇文章 示例 分析 地段 士兵 射手 属性 更多 静态 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳科技互联网 金融科技与互联网金融 互联网 的科技创新 嘟嘟瓜互联网科技 西安互联网科技公司 广州凡科互联网科技 猫创互联网科技 互联网科技公司名称 中国互联网金融科技基金 互联网之后的科技是什么 互联网科技公司有风险吗 健康食品互联网创新科技园项目 佛山市拉法互联网科技有限公司 用友工业互联网科技发展 特约风豹互联网科技为什么扣费 科技互联网海报 上海创道互联网络科技有限公司 神州科技互联网有限公司 互联网时代科技型公司的机会 北京互联网科技类企业分布 哈尔滨大商圈互联网科技有限公司 河南云网互联网络科技有限公司 中关村互联网科技集团 新华互联网科技2019 移动互联网科技股 互联网金融中的现代科技 工业互联网山东科技大学 合肥互联网科技公司公章图片 雨阳互联网卡科技有限公司 富国互联网金融科技混合基金
0