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

yizhihongxing

学习PHP设计模式是我们提高PHP技能的一个必要过程。设计模式是一种通用解决方案,用于解决常见的面向对象编程问题。本文将讲解PHP实现访问者模式的完整攻略,包括对访问者模式的介绍、访问者模式的实现步骤,以及基于PHP实现的两个示例说明。

什么是访问者模式?

访问者模式是一种行为型设计模式,它使得你能够在不改变元素类(被访问的对象)的前提下,定义作用于这些元素的新操作。

换句话说,访问者模式允许你在不改变已有类接口的情况下,定义额外的操作。这是通过将操作从类中移动并将其归结到代表这些操作的单个对象中实现的(访问者)。

当你需要添加新的操作时,只需要实现新的访问者即可。

访问者模式有两个核心角色:

  • 访问者(Visitor):为每个具体类声明一组访问操作。访问者对象使程序员可以向现有的类添加新的操作,而不必修改这些类。
  • 元素(Element):定义一个接受访问者接口(Accept)的操作,其参数是访问者对象。这个操作使访问者对象在访问元素时调用元素的方法。

PHP实现访问者模式

下面是访问者模式的实现步骤。

  1. 定义元素类。元素类定义Accept(接收访问者对象)的操作。这个操作在访问者中被调用。具体实现中,访问者参数应当以参数的形式传递到接受的方法中。

  2. 定义访问者类。访问者类定义所有具体的访问者,这些访问者类实现在特定元素上执行的算法。

  3. 所有访问者类都应该实现同一个Visitor接口。

  4. 为元素类和访问者类之间的关系定义抽象的Visitor接口。

  5. 在访问者类中实现所有要在元素类上执行的操作。

下面是两个PHP示例,展示了如何以访问者模式实现一个画图应用程序。

示例1:

<?php

interface Visitor {
    public function visitDot(Dot $dot);
    public function visitCircle(Circle $circle);
    public function visitRectangle(Rectangle $rect);
}

interface Element {
    public function accept(Visitor $visitor);
}

class Dot implements Element {
    public $name;
    public $x;
    public $y;

    public function __construct(string $name, int $x, int $y) {
        $this->name = $name;
        $this->x = $x;
        $this->y = $y;
    }

    public function accept(Visitor $visitor) {
        $visitor->visitDot($this);
    }
}

class Circle implements Element {
    public $name;
    public $x;
    public $y;
    public $radius;

    public function __construct(string $name, int $x, int $y, int $radius) {
        $this->name = $name;
        $this->x = $x;
        $this->y = $y;
        $this->radius = $radius;
    }

    public function accept(Visitor $visitor) {
        $visitor->visitCircle($this);
    }
}

class Rectangle implements Element {
    public $name;
    public $x1;
    public $y1;
    public $x2;
    public $y2;

    public function __construct(string $name, int $x1, int $y1, int $x2, int $y2) {
        $this->name = $name;
        $this->x1 = $x1;
        $this->y1 = $y1;
        $this->x2 = $x2;
        $this->y2 = $y2;
    }

    public function accept(Visitor $visitor) {
        $visitor->visitRectangle($this);
    }
}

class XMLExportVisitor implements Visitor {
    public function visitDot(Dot $dot) {
        echo '<dot x="' . $dot->x . '" y="' . $dot->y . '" name="' . $dot->name . '"/>' . PHP_EOL;
    }

    public function visitCircle(Circle $circle) {
        echo '<circle x="' . $circle->x . '" y="' . $circle->y . '" radius="' . $circle->radius . '" name="' . $circle->name . '"/>' . PHP_EOL;
    }

    public function visitRectangle(Rectangle $rect) {
        echo '<rect x1="' . $rect->x1 . '" y1="' . $rect->y1 . '" x2="' . $rect->x2 . '" y2="' . $rect->y2 . '" name="' . $rect->name . '"/>' . PHP_EOL;
    }
}

$drawing = [
    new Dot('Dot 1', 10, 20),
    new Circle('Circle 1', 20, 30, 5),
    new Rectangle('Rectangle 1', 10, 10, 20, 20)
];

$xmlExport = new XMLExportVisitor();

foreach ($drawing as $shape) {
    $shape->accept($xmlExport);
}

这个示例中展示了一个画图应用,它可以显示点、圆和矩形。这个应用中有一个XMLExportVisitor类,它能够将画图中的所有元素导出为XML格式。

示例2:

<?php

interface Visitor {
    public function visit(Soldier $soldier);
    public function visit(Lieutenant $lieutenant);
    public function visit(Commander $commander);
}

interface Unit {
    public function accept(Visitor $visitor);
}

class Commander implements Unit {
    private $name;
    private $unit = array();

    public function __construct($name) {
        $this->name = $name;
    }

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

    public function accept(Visitor $visitor) {
        $visitor->visit($this);
        foreach ($this->unit as $thisUnit) {
            $thisUnit->accept($visitor);
        }
    }
}

class Lieutenant implements Unit {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function accept(Visitor $visitor) {
        $visitor->visit($this);
    }
}

class Soldier implements Unit {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function accept(Visitor $visitor) {
        $visitor->visit($this);
    }
}

class UnitCounterVisitor implements Visitor {
    private $soldiers = 0;
    private $lieutenants = 0;
    private $commanders = 0;

    public function visit(Soldier $soldier) {
        $this->soldiers++;
    }

    public function visit(Lieutenant $lieutenant) {
        $this->lieutenants++;
    }

    public function visit(Commander $commander) {
        $this->commanders++;
    }

    public function getCounts() {
        return array('soldiers' => $this->soldiers, 'lieutenants' => $this->lieutenants, 'commanders' => $this->commanders);
    }
}

$army = new Commander('Commander');

$army->addUnit(new Lieutenant('Lieutenant 1'));
$army->addUnit(new Lieutenant('Lieutenant 2'));

$armyA = new Commander('Commander A');

$armyA->addUnit(new Soldier('Soldier 1'));
$armyA->addUnit(new Soldier('Soldier 2'));
$armyA->addUnit(new Soldier('Soldier 3'));

$armyB = new Commander('Commander B');

$armyB->addUnit(new Lieutenant('Lieutenant 3'));

$army->addUnit($armyA);
$army->addUnit($armyB);

$counter = new UnitCounterVisitor();
$army->accept($counter);

print_r($counter->getCounts());

这个示例中展示了一个军队,包括了士兵、中尉和指挥官。这个示例计算了军队中的士兵、中尉和指挥官的数量。

结论

访问者模式让我们可以通过访问者的方式,对不同的对象进行自定义操作,而不必修改它们的源代码。这种方式可以方便我们扩展和维护代码。通过本文的介绍,读者应该对访问者模式在PHP中的实现以及如何应用访问者模式来创建一个多态的应用程序有更加深刻的认识。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:学习php设计模式 php实现访问者模式(Visitor) - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • php实现将数组或对象写入到文件的方法小结【三种方法】

    下面是关于“php实现将数组或对象写入到文件的方法小结【三种方法】”的完整攻略: 1. 使用serialize()和file_put_contents()函数 可以使用PHP内置的serialize()函数将数组或对象序列化成字符串,然后通过file_put_contents()函数将字符串写入到文件中。 $data = [‘name’ => ‘Joh…

    PHP 2023年5月26日
    00
  • php数组函数序列之prev() – 移动数组内部指针到上一个元素的位置,并返回该元素值

    prev() 是一个 PHP 数组函数,它将移动内部指针到数组中的上一个元素,并返回该元素的值。它的语法如下: mixed prev ( array &$array ) 其中,$array 表示要操作的数组,它是通过引用传递而来的。 prev() 函数的工作原理是将内部指针向前移动一位,并返回当前位置的前一位元素。在访问数组中的元素时,如果不是使用特…

    PHP 2023年5月26日
    00
  • 微信卸载后重装聊天记录还能恢复吗?重装微信恢复数据方法

    微信卸载后重装聊天记录能否恢复? 如果你卸载了微信,并重装了它,你可以通过备份和恢复功能恢复聊天记录。你需要在微信卸载之前进行备份,以便在重装后进行恢复。 备份微信聊天记录流程 在微信主页,点击右上角人头图标进入个人中心 点击设置菜单,选择聊天记录迁移 选择备份聊天记录,确认操作 等待备份完成 恢复微信聊天记录流程 在重装微信之后,按照上述步骤进入个人中心 …

    PHP 2023年5月27日
    00
  • Editplus常用正则表达式介绍

    Editplus常用正则表达式介绍 正则表达式是一种用于匹配和搜索文本的高级技术。在Editplus编辑器中,可以使用正则表达式进行替换、查找等操作,提高代码或文本的编辑效率。本文将介绍一些Editplus常用的正则表达式。 1. 正则表达式基础语法 正则表达式由一些特殊的字符和普通字符组成,用于描述匹配规则。以下是一些基础的正则表达式语法: .:匹配任意一…

    PHP 2023年5月23日
    00
  • php的ajax简单实例

    下面是PHP的AJAX简单实例的完整攻略。 什么是AJAX? AJAX表示“异步JavaScript和XML”。AJAX不是新技术,而是已经存在一段时间了。它的主要目的是使Web页面具有更快的响应能力。AJAX通过在背景中与服务器进行通信的方式实现这一目的。它允许Web页面更新部分内容而不是整个页面。这意味着用户能够与Web页面进行更快的交互。 如何使用PH…

    PHP 2023年5月27日
    00
  • php读取文件内容的几种方法详解

    PHP读取文件内容的几种方法详解 在PHP中,读取文件内容是一项比较常用的操作。本文将介绍PHP读取文件内容的几种方法,包含了常用的几种方法以及一些较为高级的读取方法。 1. 使用file_get_contents()函数读取文件内容 file_get_contents()函数可用于读取文件,并且自动将文件内容读取到字符串中。 示例代码: $file_con…

    PHP 2023年5月23日
    00
  • php常用Output和ptions/Info函数集介绍

    PHP常用Output和Options/Info函数集介绍 1. Output函数集介绍 Output函数集主要用于改变PHP程序的输出流,包括在Web应用中向浏览器输出HTML,JSON等文本格式,以及在命令行应用中输出控制台的内容。 常用的Output函数有以下几个: 1. echo echo "Hello World"; echo …

    PHP 2023年5月26日
    00
  • php编写一个简单的路由类

    下面是“PHP编写一个简单的路由类”的完整攻略: 什么是路由 路由是Web开发中必不可少的一部分,它是指根据不同的URL请求,将请求转发到不同的处理程序上。Web应用程序通常由多个页面和功能组成,每一个页面和功能都有自己的URL。而路由的作用就是将这些URL和页面或功能进行映射。 设计路由类 我们可以通过PHP类来实现路由功能,下面是一个简单的路由类的设计:…

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