<?php
/** 抽象父类**/
abstract class Unit{public $depth=0;function getComposite(){return null;}function textDump($num=0){$ret="";$pad=4*$num;$ret.=sprintf("%{$pad}s","");$ret.=get_class($this);$ret.="bombard: ".$this->bombardStrength()."\n";return $ret;}function accept(ArmyVisitor $visitor){$method="visit".get_class($this);//得到类名然后再组合成ArmyVisitor下面的函数名$visitor->$method($this);//然后再执行函数}protected function setDepth($depth){$this->depth=$depth;}function getDepth(){return $this->depth;}abstract function bombardStrength();
}
/**抽象子类继承父类**/
abstract class CompositeUnit extends Unit{private $units=array();function getComposite(){return $this;}protected function units(){return $this->units;}function textDump($num=0){$ret=parent::textDump($num);foreach($this->units as $unit){$ret.=$unit->textDump($num+1);}return $ret;}function removeUnit(Unit $unit){foreach($this->units as $key=>$val){if($unit==$val){unset($this->units[$key]);}}return $this->units;}function addUnit(Unit $unit){foreach($this->units as $thisunit){if($unit===$thisunit){return;}}$unit->setDepth($this->depth+1);//在添加实例时运行setDepth()函数确实子类深度$this->units[]=$unit;}function accept(ArmyVisitor $visitor){parent::accept($visitor);foreach( $this->units as $thisunit){//历遍类,再调用类里面的accept()函数$thisunit->accept($visitor);}}
}
class Archer extends Unit{function bombardStrength(){return 10;}
}
class LaserCannon extends Unit{function bombardStrength(){return 20;}
}
class Cavalry extends Unit{function bombardStrength(){return 30;}
}
class TroopCarrier extends CompositeUnit{function bombardStrength(){$ret=0;/*数组里面是对象,那循环输出时就要加()*/foreach($this->units() as $unit){$ret+=$unit->bombardStrength();}return $ret;}
}
class Army extends CompositeUnit{function bombardStrength(){$ret=0;foreach($this->units() as $unit){$ret+=$unit->bombardStrength();}return $ret;}
}
//抽象的组合类
abstract class ArmyVisitor{abstract function visit(Unit $node);function visitArcher(Archer $node){$this->visit($node);}function visitCavalry(Cavalry $node){$this->visit($node);}function visitLaserCannon(LaserCannon $node){$this->visit($node);}function visitTroopCarrier(TroopCarrier $node){$this->visit($node);}function visitArmy(Army $node){$this->visit($node);}
}
class TextDumpArmyVisitor extends ArmyVisitor{private $text='';function visit(Unit $node){$ret='';$pad=4*$node->getDepth();$ret.=get_class($node).": ";$ret.="bombard:".$node->bombardStrength()."<br>";$this->text.=$ret;}function getText(){return $this->text;}
}
//税率类,每个观察者的税率
class TaxCollectionVisitor extends ArmyVisitor{private $due=0;private $report="";function visit(Unit $node){$this->levy($node,1);}function visitCavalry(Cavalry $node){$this->levy($node,2);}function visitArcher(Archer $node){$this->levy($node,2);}function visitTroopCarrier(TroopCarrier $node){$this->levy($node,3);}function visitLaserCannon(LaserCannon $node){$this->levy($node,2.5);}private function levy(Unit $unit,$amount){$this->report .="征收税率为:".get_class($unit);$this->report .=": $amount <br>";$this->due+=$amount;}function getReport(){return $this->report;}function getTax(){return $this->due;}
}
/**这个类是用来调用实例化的,也可以不用写这个类,自己直接调用**/
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=new Army();
$main->addUnit(new Archer());
$main->addUnit(new LaserCannon());
$main->addUnit(new Cavalry());
$text=new TaxCollectionVisitor();
$main->accept($text);
echo "税率合计: ";
echo $text->getTax();
echo "<br>";
echo $text->getReport();
?>

php观察者模式,组合ArmyVisitor抽象类,用accept()方法将访问者对象传递给当前对象的所有的子元素,当前组件是一个组合体相关推荐

  1. android集合方法,android中intent传递list或者对象的方法

    本文实例讲述了android中intent传递list或者对象的方法.分享给大家供大家参考.具体实现方法如下: 方法一: 如果单纯的传递List 或者List的话 就可以直接使用 代码如下: inte ...

  2. 组合体视图的画图步骤_画组合体视图的方法与步骤

    一.画组合体视图的方法与步骤 在画组合体的三视图之前,首先运用形体分析法对组合体进行分析,确定它们的组合形式,判断形体间邻接表面的相对位置:其次逐个画出形体的三视图:最后对组合体中的各种面进行面.线的 ...

  3. html让空间高度跟随父级,CSS子元素跟父元素的高度一致的实现方法

    绝对定位方法: (1)将父元素设置为相对定位,不写父元素的高度时,会随着左边的子元素高度变化而变化 .parent { /*关键代码*/ position: relative; /*其他样式*/ wi ...

  4. 初始Java Java SE 包,继承,组合,多态,抽象类,接口

    目录 包 1.静态导入 2.将类放到包中 3.包的访问权限控制 继承 基本语法: 注意事项: protected 关键字 final 关键字 组合 多态 向上转型: 动态绑定 方法重写 重写的规则 : ...

  5. 深入讨论.NET Socket的Accept方法

    深入讨论.NET  Socket的Accept方法 考虑一个问题,假如同时有50个连接请求进入一个服务器(这种情况对于普通负载的Web服务器都是很常见的)会怎么样?阻塞式I/O只能循环调用Accept ...

  6. 中单引号怎么转义_在JavaScript中组合字符串的4种方法

    下面是在JavaScript中组合字符串的4种方法.我最喜欢的方法是使用模板字符串.为什么?因为它更具可读性,所以没有转义引号的反斜杠,没有笨拙的空格分隔符,也没有混乱的加号操作符 . const i ...

  7. 索引的使用以及常见索引类型,组合索引的具体使用方法。

    索引是数据库中的一种预先建立的数据结构,用于加速数据的检索速度.在数据库中,通常会在一个表中的一个字段上建立索引,以便快速查询该字段的数据. 常见的索引类型包括: 单列索引:只包含单个字段的索引. 联 ...

  8. 继承了抽象类的子类需要把抽象类中的方法重写一遍吗?

    继承了抽象类的子类需要把抽象类中的方法重写一遍吗? 抽象类中的非抽象方法不用重写,其他必须重写,接口的方法必须重写: 接口和抽象类中只有方法名,没有定义的,如果你不定义 也就是空方法,接口就是为了弥补 ...

  9. Numpy 组合数组的几种方法

    来自 <Python数据分析基础教程:Numpy 学习指南(第2版)> 下面将介绍组合数组的几种方法: 水平组合 垂直组合 深度组合 列组合 行组合 0.创建两个3*3的数组 from n ...

  10. 在JavaScript中组合字符串的4种方法

    下面是在JavaScript中组合字符串的4种方法.我最喜欢的方法是使用模板字符串.为什么?因为它更具可读性,所以没有转义引号的反斜杠,没有笨拙的空格分隔符,也没有混乱的加号操作符

最新文章

  1. .Net Reactor 5脱壳教程
  2. SAP中的KANBAN
  3. 成功解决OSError: dlopen() failed to load a library: cairo / cairo-2 / cairo-gobject-2 / cairo.so.2
  4. 排序算法系列:快速排序算法
  5. 18.8.20 考试总结
  6. Tomcat启动项目没问题,网页一片空白
  7. 没有qpress_MySQL 大数据备份方案之Percona XtraBackup
  8. python 通讯录系统_Python下的通讯录
  9. CSAPP-C1-计算机系统漫游
  10. 使用POI创建PPT
  11. 华为无线模板之间的应用关系图
  12. 多种方法使用c语言读写文件(总结)
  13. 计算100以内奇数和偶数的数量
  14. 自定义 Chrome (谷歌浏览器) 主题
  15. Ubuntu部署YAPI
  16. Python基础入门自学——18--操作Excel-工作实践需求
  17. windows10+ubuntu 16 04+双硬盘(SSD+HDD)分区(图文)
  18. IDEA快捷键大全,各类IDEA快捷键
  19. 【Python入门教程】第85篇 常用字符串方法之大小写判断
  20. 【信息安全课程设计】字典破解密码

热门文章

  1. 木瓜移动每日出海快讯0428:谷歌发布Q1财报
  2. Java:javax.mail通过163服务器发送邮件
  3. XLua官方教程 06 热更新实例 hotfix样例
  4. 从事IT业一个8年老兵转行前的自我总结1——初爻
  5. Flink 系例 之 Fold
  6. linux系统及编程基础唐晓君,Linux-Shell编程之判断文件类型
  7. Python参考文献
  8. python爬虫qq音乐歌词_10、 在QQ音乐中爬取某首歌曲的歌词
  9. 系统更新win10服务器出错怎么办,windows10更新升级失败0x80072ee2解决方法
  10. Java模拟新浪微博登陆抓取数据