加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

浅谈PHP面向工具之会见者模式+组合模式

发布时间:2021-01-18 02:18:26 所属栏目:编程 来源:网络整理
导读:由于原文中连续了组合模式的代码示例来讲会见者模式 以是这里就归并一路来温习了。但首要照旧讲会见者模式。顾名思义这个模式会有一个会见者类(就像近期的热播剧“人民的名义”中的搜查官,跑到到贪官家里观测取证,查实后就治罪),被会见者类挪用会见者类
副问题[/!--empirenews.page--]

由于原文中连续了组合模式的代码示例来讲会见者模式 以是这里就归并一路来温习了。但首要照旧讲会见者模式。顾名思义这个模式会有一个会见者类(就像近期的热播剧“人民的名义”中的搜查官,跑到到贪官家里观测取证,查实后就治罪),被会见者类挪用会见者类的时辰会将自身转达给它行使。

直接看代码:

abstract class Unit {
  abstract function bombardStrength();  //获取单元的进攻力
  

  //这个要领将挪用会见者类,并将自身转达给它
  function accept(ArmyVisitor $visitor){
    $method = "visit" . get_class($this);
    $visitor->$method($this);      //挪用会见者类的要领,这里行使了 "visit" . get_class($this) 构成了要领的名称
  }
  

  //按原文的说法是配置一个深度,固然之后会有挪用但这个要领对付领略这个模式不重要可以不消管他(原文示例代码中常常有些跟领略模式道理没太多相关的代码)
  protected function setDepth($depth){
    $this->depth = $depth;
  }

  function getDepth(){
    return $this->depth;
  }
}

//弓箭手
class Archer extends Unit{
  function bombardStrength(){
    return 4;
  }
}

//激光炮

class LaserCannonUnit extends Unit{
  function bombardStrength(){
    return 44;
  }
}

//骑兵

class Cavalry extends Unit{
  function bombardStrength(){
    return 2;          //骑兵的进攻力居然比弓箭手低?

  }
}

//用于组合担任了unit类的实例,并让Army和TroopCarrier类担任removeUnit和addUnit要领,不放基类是由于上述的三个类已经是最小单元了不是一个军事团体removeUnit和addUnit要领对他们没用。

abstract class CompositeUnit extends Unit{
  private $units = array();    //存放任何担任了unit 类的实例

  function getComposite(){   //这个要领首要用于判定当前实例是否是一个 CompositeUnit 类
    return $this;
  }

  protected function units(){
    return $this->units;
  }

  function removeUnit(Unit $unit){    //删除一个军事单元
    $this->units = array_udiff(
      $this->units,array($unit),      function($a,$b){return ($a === $b)?0:1;}

    );  
  }

  function addUnit(Unit $unit){        //添加一个军事单元
    if(in_array($unit,$this->units,true)){
      return;
    }
    $unit->setDepth($this->depth + 1);  
    $this->units[] = $unit;
  }

  function bombardStrength(){
    $ret = 0;
    foreach($this->units as $unit){
      $ret +=$unit->bombardStrength();
    }
    return $ret;
  }

  function accept(Armyvisitor $visitor){    //挪用会见者
    parent::accept($visitor);        //挪用基类的accept要领,在第一个客户端代码条用里将会生涯军事团体整体的一个信息
    foreach($this->units as $thisunit){   //挪用军事单元accept要领,在第一个客户端代码条用里将会生涯个中每一个军事单元的信息
      $thisunit->accept($visitor);
    }
  }
}

//部队

class Army extends CompositeUnit {

}

//舰队

class TroopCarrier extends CompositeUnit {

}

//会见者类

abstract class ArmyVisitor{
  abstract function visit(Unit $node);  //会见者要执行的营业逻辑
  function visitArcher(Archer $node){  //着实我认为对付领略来嗣魅这个抽象类有一个抽象要领visit()就够了,原文还多出下面这些要领来绕个圈挪用visit

    //......
    $this->visit($node);
  }

  function visitCavalry(Cavalry $node){

    //.......
    $this->visit($node);
  }

  function visitLaserCannonUnit(LaserCannonUnit $node){

    //......
    $this->visit($node);
  }

  function visitTroopCarrierUnit(Cavalry $node){

    //......
    $this->visit($node);
  }

  function visitArmy(Cavalry $node){

    //......
    $this->visit($node);
  }
}

//这个会见者类首要用于获取并生涯被会见者工具的信息
class TextDumpArmyVisitor extends ArmyVisitor {
  private $text = "";
  function visit(Unit $node){
    $ret = "";
    $pad = 4 * $node->getDpth();
    $ret .= sprintf("%{$pad}s","");
    $ret .=get_class($node).": ";
    $ret .= "bombard: " . $node->bombardStrength() . "n";
    $this->text .=$ret;
  }

  function getText(){
    return $this->text;
  }
}

//用于向每个工具征税的会见者类,客户端代码2中将会挪用
class TaxCollectionVisitor extends ArmyVisitor{
  private $due=0;
  private $report ="";

  function visit(Unit $node){
    $this->levy($node,1);
  }

  function visitArcher(Archer $node){    //复写了父类的要领,对付差异的单元征收差异的税
    $this->levy($node,2);
  }

  function visitCavalry(Cavalry $node){
    $this->levy($node,3);
  }

  function visitTroopCarrierUnit(TroopCarrierUnit $node){
    $this->levy($node,5);
  }

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读