轻松掌握php设计模式之访问者模式

访问者模式解决的问题

在我们的代码编写过程当中,经常需要对一些类似的对象添加一些的代码,我们以一个计算机对象打印组成部分为例来看下:

  /**
  * 抽象基类
  */
  abstract class Unit
  {
    /**
    *获取名称
    */
    abstract public function getName();

  }

  /**
  * Cpu类
  */
  class Cpu extends Unit
  {
    public function getName()
    {
      return 'i am cpu';
    }
  }

  /**
  * 内存类
  */
  class Memory extends Unit
  {
    public function getName()
    {
      return 'i am memory';
    }
  }

  /**
  * 键盘类
  */
  class Keyboard extends Unit
  {
    public function getName()
    {
      return 'i am keyboard';
    }
  }

  /**
  * 计算机类
  */
  class Computer
  {
    protected $_items = [];

    public function add(Unit $unit)
    {
      $this->_items[] = $unit;
    }

    public function print()
    {
      // 循环打印各个组成部分
      foreach ($this->_items as $item) {
        $item->getName();
      }
    }
  }

这个时候上面的代码看上去好像很完美的样子,但是问题来了,现在我们不但需要打印组成部分,还需要保存各个组件到数据库,不仅如此,还需要打印各个组件的价格;此时如果在Unit基类中添加getPrice()和save()方法,也能实现我们想要的功能,但是这样做也存在问题,你并不知道还需要新增什么操作,如果每新增一个操作都用这样的方法来新增,我们的类会变得越来越臃肿。

访问者模式的实现

而访问者模式就是为了解决这个问题的,他把数据结构和作用于结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化,我们来看下面改良过得代码:

  /**
  * 抽象基类
  */
  abstract class Unit
  {
    /**
    * 获取名称
    */
    abstract public function getName();

    /**
    * 用来接受访问者对象,回调访问者的visit方法
    * 非常关键的方法
    */
    public function accept(Visitor $visitor)
    {
      $method = visit . get_class($this);
      if (method_exists($visitor, $method)) {
        $visitor->$method($this);
      }
    }
  }

  /**
  * Cpu类
  */
  class Cpu extends Unit
  {
    public function getName()
    {
      return 'i am cpu';
    }
  }

  /**
  * Memory类
  */
  class Memory extends Unit
  {
    public function getName()
    {
      return 'i am memory';
    }
  }

  /**
  * Keyboard类
  */
  class Keyboard extends Unit
  {
    public function getName()
    {
      return 'i am keyboard';
    }
  }

  /**
  * Keyboard类
  */
  interface Visitor
  {
    public function visitCpu(Cpu $cpu);
    public function visitMemory(Memory $memory);
    public function visitKeyboard(Keyboard $keyboard);
  }

  /**
  *
  */
  class PrintVisitor implements Visitor
  {
    public function visitCpu(Cpu $cpu)
    {
      echo "hello, " . $cpu->getName() . "\n";
    }

    public function visitMemory(Memory $memory)
    {
      echo "hello, " . $memory->getName() . "\n";
    }

    public function visitKeyboard(Keyboard $keyboard)
    {
      echo "hello, " . $keyboard->getName() . "\n";
    }
  }

  /**
  *
  */
  class Computer
  {
    protected $_items = [];

    public function add(Unit $unit)
    {
      $this->_items[] = $unit;
    }

    /**
    * 调用各个组件的accept方法
    */
    public function accept(Visitor $visitor)
    {
      foreach ($this->_items as $item) {
        $item->accept($visitor);
      }
    }
  }

  $computer = new Computer();
  $computer->add(new Cpu());
  $computer->add(new Memory());
  $computer->add(new Keyboard());

  $printVisitor = new PrintVisitor();
  $computer->print($printVisitor);

  // 以上的代码将打印出
  hello, i am cpu
  hello, i am memory
  hello, i am keyboard

总结

经过上面的改良之后,我们要扩展就变得非常容易,如果我们需要新增保存到数据库的方法,可以在新增一个实现了Visitor的类,比如SaveVisitor,在该类中来实现保存的方法,等于我们把该类和该类中的一些操作解藕了出来,而集合了类操作的对象就是访问者。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈PHP面向对象之访问者模式+组合模式

    因为原文中延续了组合模式的代码示例来讲访问者模式 所以这里就合并一起来复习了.但主要还是讲访问者模式.顾名思义这个模式会有一个访问者类(就像近期的热播剧"人民的名义"中的检查官,跑到到贪官家里调查取证,查实后就定罪),被访问者类调用访问者类的时候会将自身传递给它使用. 直接看代码: //被访问者基类 abstract class Unit { abstract function bombardStrength(); //获取单位的攻击力 //这个方法将调用访问者类,并将自身传递给它 f

  • 深入php面向对象、模式与实践

    1 语法 1.1 基础语法 clone 需要操作原对象,但又不想影响原对象. 复制代码 代码如下: $K_back = clone $K; 基本数据类型和数组都为真复制,即为真副本,当属性为对象时,为假复制,改变副本仍会影响原对象.解决方案: //在原对象中添加 function __clone(){ $this->对象 = clone $this->对象 } __clone在clone前自动触发,可以执行一些在备份前的属性操作. 2.&传递引用 方法引用传递,改变源对象 复制代码 代

  • PHP面向对象程序设计组合模式与装饰模式详解

    本文实例讲述了PHP面向对象程序设计组合模式与装饰模式.分享给大家供大家参考,具体如下: 组合模式 定义:组合模式定义了一个单根继承体系,使具有截然不同职责的集合可以并肩工作. 一个军队的案例, <?php abstract class Unit { // 个体 abstract function bombardStrength(); } class Archer extends Unit { // 弓箭手 function bombardStrength() { return 4; } } c

  • 学习php设计模式 php实现访问者模式(Visitor)

    访问者模式表示一个作用于某对象结构中各元素的操作.它可以在不修改各元素类的前提下定义作用于这些元素的新操作,即动态的增加具体访问者角色. 访问者模式利用了双重分派.先将访问者传入元素对象的Accept方法中,然后元素对象再将自己传入访问者,之后访问者执行元素的相应方法. 访问者模式多用在聚集类型多样的情况下.在普通的形式下必须判断每个元素是属于什么类型然后进行相应的操作,从而诞生出冗长的条件转移语句.而访问者模式则可以比较好的解决这个问题.对每个元素统一调用$element->accept($v

  • 轻松掌握php设计模式之访问者模式

    访问者模式解决的问题 在我们的代码编写过程当中,经常需要对一些类似的对象添加一些的代码,我们以一个计算机对象打印组成部分为例来看下: /** * 抽象基类 */ abstract class Unit { /** *获取名称 */ abstract public function getName(); } /** * Cpu类 */ class Cpu extends Unit { public function getName() { return 'i am cpu'; } } /** *

  • 轻松掌握python设计模式之访问者模式

    本文实例为大家分享了python访问者模式代码,供大家参考,具体内容如下 """访问者模式""" class Node(object): pass class A(Node): pass class B(Node): pass class C(A, B): pass class Visitor(object): def visit(self, node, *args, **kwargs): meth = None ""&quo

  • JAVA设计模式之访问者模式原理与用法详解

    本文实例讲述了JAVA设计模式之访问者模式.分享给大家供大家参考,具体如下: 访问者模式: 一个作用于某对象结构中各元素的操作,使你可以在不改变各元素类数据结构的前提下增加作用于这些元素的新操作. 结构对象是访问者模式必备条件,且这个结构对象必须存在遍历自身各个对象的方法. 适用于:数据结构相对稳定,把数据结构和作用与其上的其它操作解耦,使得操作相对自由. 优点: 1.符合单一职责原则 2.扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展. 缺点: 1.如果要增加新元素,则会让操

  • Java设计模式之访问者模式使用场景及代码示例

    Java设计模式访问者模式 模式概念 访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作.访问者模式适用于数据结构相对稳定算法又易变化的系统,若系统数据结构对象易于变化,则不适合使用访问者模式.访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者. Visitor应用场景 一定会有的疑问:visitor和iterator的区别: visitor可以访问不同的对象(只需要在Element定义对应的accept),但是Ite

  • Android编程设计模式之访问者模式详解

    本文实例讲述了Android编程设计模式之访问者模式.分享给大家供大家参考,具体如下: 一.介绍 访问者模式是一种将数据操作与数据结构分离的设计模式,它是<设计模式>中23种设计模式中最复杂的一个,但它的使用频率并不高,正如<设计模式>的作者GOF对访问者模式的描述:大多数情况下,你不需要使用访问者模式,但是当你一旦需要使用它时,那你就是真的需要它了. 访问者模式的基本想法是,软件系统中拥有一个由许多对象构成的.比较稳定的对象结构,这些对象的类都拥有一个accept方法用来接受访问

  • JS设计模式之访问者模式定义与用法分析

    本文实例讲述了JS设计模式之访问者模式定义与用法.分享给大家供大家参考,具体如下: 在访问者模式中,主要包括下面几个角色 1.抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的. 2.访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情. 3.抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的.抽象元素一般有两类方法,一部分是本身的业务逻辑,另外

  • .Net行为型设计模式之访问者模式(Visitor)

    目录 一.动机(Motivate) 二.意图(Intent) 三.结构图(Structure) 四.模式的组成 五.访问者模式的代码实现 六.访问者模式的实现要点: (1).访问者模式的主要优点有: (2).访问者模式的主要缺点有: (3).在下面的情况下可以考虑使用访问者模式: 七..NET 访问者模式的实现 一.动机(Motivate) 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设

  • C++设计模式之访问者模式

    前言 这是23+1(简单工厂模式)之中的最后一个了--访问者模式.访问者模式也是一个比较麻烦的设计模式.我也没有实战经验,对于访问者模式的理解完全来自GOF的<设计模式:可复用面向对象软件的基础>,而这篇文章就是根据对这本书的理解而写出来的.在读<设计模式:可复用面向对象软件的基础>的时候,让我想起自己做过的一个项目,该项目虽然没有使用访问者模式,但是,今天理解了该模式,如果使用该模式对之前做过的项目进行重构,将是一个不错的想法. 访问者模式 在GOF的<设计模式:可复用面向

  • C语言 设计模式之访问者模式

    C语言访问者模式 概要: 访问者模式,听上去复杂一些.但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉.比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐.可是,不同的地方的人未必都喜欢这两种豆腐.四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些.那么,这种情况应该怎么用设计模式表达呢? typedef struct _Tofu { int type; void (*eat) (struct _Visitor* pVisitor, struct _Tofu* pTo

  • JAVA设计模式之访问者模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: 复制代码 代码如下: List lis

随机推荐