浅谈PHP设计模式的访问者模式

简介:

访问者模式,属于行为型的设计模式。表示一个作用于某对象结构中的各元素的操作。它是你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

适用场景:

  1. 类中有易于变化的算法。
  2. 希望数据结构与数据分离。

优点:

  1. 便于增加新的操作,相当于增加一个访问者。访问者模式将有关行为集中到一个访问者对象中。

缺点:

元素变更比较困难,如为被访问的对象增加、减少一些属性,相应的访问者也需要进行修改 ;

代码:

/**
 *Component接口声明了一个“accept”方法,该方法应将base访问者接口作为参数。
 */
interface Component
{
    public function accept(Visitor $visitor): void;
}

/**
 *每个具体组件必须以这样的方式实现“accept”方法:它调用与组件类对应的访问者方法。
 */
class ConcreteComponentA implements Component
{
    /*
     * 注意,我们调用的是与当前类名匹配的“visitContainerComponentA”。通过这种方式,我们让访问者知道它所使用的组件的类
     */
    public function accept(Visitor $visitor): void
    {
        $visitor->visitConcreteComponentA($this);
    }

    /*
     * 具体组件可能具有其基类或接口中不存在的特殊方法。Visitor仍然能够使用这些方法,因为它知道组件的具体类
     */
    public function exclusiveMethodOfConcreteComponentA(): string
    {
        return "A";
    }
}

class ConcreteComponentB implements Component
{
    /**
     * 此处相同:visitContainerComponentB=>ConcreteComponentB
     */
    public function accept(Visitor $visitor): void
    {
        $visitor->visitConcreteComponentB($this);
    }

    public function specialMethodOfConcreteComponentB(): string
    {
        return "B";
    }
}

/**
 *Visitor接口声明了一组与组件类相对应的访问方法。访问方法的签名允许访问者标识它正在处理的组件的确切类。
 */
interface Visitor
{
    public function visitConcreteComponentA(ConcreteComponentA $element): void;

    public function visitConcreteComponentB(ConcreteComponentB $element): void;
}

/**
 *Concrete Visitors实现了同一算法的多个版本,它可以与所有具体组件类一起工作。当将Visitor模式与复杂的对象结构(如Composite树)一起使用时,您可以体验到它的最大好处。在这种情况下,在对结构的各个对象执行访问者的方法时,存储算法的一些中间状态可能会有所帮助。
 */
class ConcreteVisitor1 implements Visitor
{
    public function visitConcreteComponentA(ConcreteComponentA $element): void
    {
        echo $element->exclusiveMethodOfConcreteComponentA() . " + ConcreteVisitor1\n";
    }

    public function visitConcreteComponentB(ConcreteComponentB $element): void
    {
        echo $element->specialMethodOfConcreteComponentB() . " + ConcreteVisitor1\n";
    }
}

class ConcreteVisitor2 implements Visitor
{
    public function visitConcreteComponentA(ConcreteComponentA $element): void
    {
        echo $element->exclusiveMethodOfConcreteComponentA() . " + ConcreteVisitor2\n";
    }

    public function visitConcreteComponentB(ConcreteComponentB $element): void
    {
        echo $element->specialMethodOfConcreteComponentB() . " + ConcreteVisitor2\n";
    }
}

/**
 *客户端代码可以在任何一组元素上运行访问者操作,而无需弄清楚它们的具体类。accept操作将调用指向访问者对象中的适当操作。
 */
function clientCode(array $components, Visitor $visitor)
{
    // ...
    foreach ($components as $component) {
        $component->accept($visitor);
    }
    // ...
}


//调用端
$components = [
    new ConcreteComponentA(),
    new ConcreteComponentB(),
];

echo "客户端代码通过基本访问者界面与所有访问者一起工作:\n";
$visitor1 = new ConcreteVisitor1();
clientCode($components, $visitor1);
echo "\n";

echo "它允许相同的客户端代码与不同类型的访问者一起工作:\n";
$visitor2 = new ConcreteVisitor2();
clientCode($components, $visitor2);

原文链接:https://www.cnblogs.com/phpphp/p/17069476.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈PHP设计模式的访问者模式 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • php基于 swoole 实现的异步处理任务功能示例

    下面是 “php基于 swoole 实现的异步处理任务功能示例” 的完整攻略: Swoole Swoole 是一个基于 PHP 的异步、协程网络通信引擎,被广泛用于构建高性能、高可靠的网络应用程序。通过 Swoole,我们可以像编写同步代码一样编写异步代码,在同时处理多个客户端请求时提供出色的性能。 PHP异步任务处理 PHP 基于 Swoole 提供了一种…

    PHP 2023年5月23日
    00
  • php截取utf-8中文字符串乱码的解决方法

    针对“php截取utf-8中文字符串乱码的解决方法”,这里给出一份完整的攻略,并提供两个示例说明。文中会有代码块,需注意格式和缩进。 1. 问题描述 在使用PHP解析UTF-8编码的中文字符时,经常会出现乱码。尤其是在使用substr()或mb_substr()函数截取中文字符时,更是容易出现乱码的情况。 2. 原理解释 在UTF-8编码中,一个汉字占3个字…

    PHP 2023年5月26日
    00
  • PHP实现合并两个排序链表的方法

    PHP实现合并两个排序链表的方法 1. 思路 定义一个新的链表,用来存放合并后的元素 依次比较两个链表中的元素大小,较小的元素作为新链表的头节点,将其后继指向较大元素的头节点 重复以上步骤,直到其中一个链表为空 将非空链表的剩余元素依次加入到新链表的末尾 2. 代码实现 class ListNode { public $val = 0; public $ne…

    PHP 2023年5月26日
    00
  • PHP编程入门的基本语法知识点总结

    PHP编程入门的基本语法知识点总结 变量 PHP中变量以$符号开头,可以存储各种类型的数据,如字符串、整数、浮点数、数组等等。 示例代码: $name = ‘Tom’; $age = 20; $height = 1.75; $fruits = [‘apple’,’banana’,’pear’]; 数据类型 PHP支持多种数据类型,包括字符串、整数、浮点数、布…

    PHP 2023年5月30日
    00
  • ThinkPHP钩子和行为获取回调参数和自定义参数

    0x001 自定义参数 $extra_param = “Some extra param”; Hook::add(‘response_end’, function($params) use ($extra_param) { Log::info(‘Extra: ‘.$extra_param); }); 原文链接:https://www.cnblogs.com/…

    PHP 2023年4月18日
    00
  • PHP二维数组实现去除重复项的方法【保留各个键值】

    以下是详细讲解PHP二维数组实现去除重复项的方法【保留各个键值】的攻略。 1. 问题概述 在开发中,经常会遇到需要将二维数组中的重复项去除的情况,例如,以下这个二维数组: $users = [ [‘name’ => ‘John’, ‘age’ => 20], [‘name’ => ‘Mary’, ‘age’ => 22], [‘nam…

    PHP 2023年5月26日
    00
  • php基于curl实现的股票信息查询类实例

    下面我将详细讲解 “php基于curl实现的股票信息查询类实例” 的完整攻略,内容如下: 1. 什么是curl? Curl是一个用于传输数据的工具和库,支持多种协议,包括HTTP、FTP、TELNET、Gopher等。curl常用于与Web服务器进行数据交互或抓取网页数据。 2. 使用方法 2.1 安装curl 在使用curl之前,需要确保你的PHP环境已经…

    PHP 2023年5月26日
    00
  • PHP编程实现脚本异步执行的方法

    实现PHP脚本异步执行有多种方法,下面将介绍其中两种主要方法: 使用pcntl_fork()函数进行异步执行 该方法需要使用到pcntl扩展。它允许我们创建一个子进程,并在子进程中执行需要异步处理的任务。示例代码如下: <?php // 父进程代码 $pid = pcntl_fork(); if ($pid == -1) { // 创建子进程失败 ex…

    PHP 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部