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

学习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日

相关文章

  • php7连接MySQL实现简易查询程序的方法

    下面是详细的攻略: PHP7连接MySQL实现简易查询程序 前置条件 在开始编写PHP7连接MySQL实现简易查询程序之前,需要先确保以下条件: 已经安装了PHP7和MySQL数据库 确认已经能够通过PHP连接MySQL 连接MySQL 首先,需要在PHP中建立与MySQL数据库的连接。这可以通过使用 mysqli_connect() 函数来实现。 <…

    PHP 2023年5月30日
    00
  • PHP框架的选择及几款主流框架的性能基本评测

    PHP框架的选择及几款主流框架的性能基本评测 选择PHP框架的原则 选择一个适合自己的PHP框架很重要,以下是选择PHP框架时的一些原则: 框架越流行,支持越好,社区较大,遇到的问题可以在社区中很快得到解决。 框架性能优良,能够支持高并发,对内存占用低。 框架的文档详细、规范,易于上手和维护。 框架的特点和优势要符合项目需求,确定应用场景和架构需求。 主流P…

    PHP 2023年5月30日
    00
  • 微信小程序 获取设备信息 API实例详解

    微信小程序 获取设备信息API实例详解 微信小程序提供了获取设备信息的API,可以通过该API获取设备的基本信息,例如设备型号、操作系统版本、客户端平台等。本文将详细讲解如何使用该API。 获取设备信息API 在小程序中,可以通过 wx.getSystemInfo() 方法获取设备信息,该方法返回一个对象,包含了设备的基本信息。 该方法的语法如下: wx.g…

    PHP 2023年5月23日
    00
  • PHP简单判断字符串是否包含另一个字符串的方法

    下面是“PHP简单判断字符串是否包含另一个字符串的方法”的完整攻略。 1. 使用strpos()函数 PHP提供了一个内置函数strpos(),可以用来判断一个字符串是否包含另一个字符串。其函数声明如下: int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) 其中,第一个参数…

    PHP 2023年5月26日
    00
  • php调用自己java程序的方法详解

    针对“php调用自己java程序的方法详解”,我们可以从以下三个方面进行讲解: Java程序的封装和构建 PHP调用Java程序的方法 示例说明 1. Java程序的封装和构建 首先,我们需要将Java程序封装成jar包,这可以通过Eclipse等Java开发工具实现: 进入Eclipse,打开Java工程。 右键点击该工程,选择Export,找到Java中…

    PHP 2023年5月26日
    00
  • 微信好友添加到桌面的图文教程

    关于“微信好友添加到桌面的图文教程”的完整攻略,以下是详细的讲解。 一、背景 随着移动互联网应用的不断普及,许多用户习惯于将常用应用添加到手机桌面上,以便快速打开使用。微信作为目前最为流行的社交软件之一,也提供了将好友聊天窗口添加到桌面的功能。 二、微信好友添加到桌面方法 微信好友聊天窗口添加到桌面的方法如下: 首先进入微信的聊天界面。 找到要添加到桌面的好…

    PHP 2023年5月30日
    00
  • php绘图之加载外部图片的方法

    如何在 PHP 中加载外部图片并且进行绘图呢?这里提供两种方法:使用 GD 库和使用 Imagick 库。 使用 GD 库 使用 GD 库,你可以使用 PHP 在一张图片上绘制基本的形状、文字、边框等等。接下来是使用 GD 绘制一张图片,并在其上添加另一张图片的示例代码: <?php // 创建一个画布 $image = imagecreatetrue…

    PHP 2023年5月30日
    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
合作推广
合作推广
分享本页
返回顶部