PHP设计模式:访问者模式

php·编程语言 · 2015-12-25

概述

访问者模式是一种行为型设计模式,它允许你在不修改对象结构的前提下定义新的操作。通过将操作封装在访问者对象中,访问者模式可以让你在不同的对象上执行不同的操作。

适用场景

访问者模式适用于以下情况:

  • 当对象结构包含多个不同类型的对象,并且你希望对这些对象执行不同的操作时。
  • 当你希望在不修改对象类的前提下,新增一些新的操作或行为。
  • 当对象结构经常变化,但操作算法保持相对稳定时。

结构

访问者模式由以下组件组成:

  • 抽象元素(Abstract Element):抽象元素定义了接受访问者对象的接口。
  • 具体元素(Concrete Element):具体元素是抽象元素的实现,它提供了接受访问者对象的具体实现。
  • 抽象访问者(Abstract Visitor):抽象访问者定义了访问具体元素的接口。
  • 具体访问者(Concrete Visitor):具体访问者实现了抽象访问者定义的接口,并对具体元素执行相应的操作。
  • 对象结构(Object Structure):对象结构是一个容器,它存储了多个不同类型的元素,并提供了遍历元素的方法。

示例

<?php

// 抽象元素
interface Element
{
    public function accept(Visitor $visitor);
}

// 具体元素A
class ConcreteElementA implements Element
{
    public function accept(Visitor $visitor)
    {
        $visitor->visitElementA($this);
    }

    public function operationA()
    {
        echo "执行具体元素A的操作。" . PHP_EOL;
    }
}

// 具体元素B
class ConcreteElementB implements Element
{
    public function accept(Visitor $visitor)
    {
        $visitor->visitElementB($this);
    }

    public function operationB()
    {
        echo "执行具体元素B的操作。" . PHP_EOL;
    }
}

// 抽象访问者
interface Visitor
{
    public function visitElementA(ConcreteElementA $elementA);
    public function visitElementB(ConcreteElementB $elementB);
}

// 具体访问者
class ConcreteVisitor implements Visitor
{
    public function visitElementA(ConcreteElementA $elementA)
    {
        echo "访问者访问具体元素A,执行相应操作。" . PHP_EOL;
        $elementA->operationA();
    }

    public function visitElementB(ConcreteElementB $elementB)
    {
        echo "访问者访问具体元素B,执行相应操作。" . PHP_EOL;
        $elementB->operationB();
    }
}

// 对象结构
class ObjectStructure
{
    private $elements = [];

    public function attach(Element $element)
    {
        $this->elements[] = $element;
    }

    public function detach(Element $element)
    {
        $index = array_search($element, $this->elements, true);
        if ($index !== false) {
            unset($this->elements[$index]);
        }
    }

    public function accept(Visitor $visitor)
    {
        foreach ($this->elements as $element) {
            $element->accept($visitor);
        }
    }
}

// 客户端代码
$objectStructure = new ObjectStructure();

$elementA = new ConcreteElementA();
$elementB = new ConcreteElementB();

$objectStructure->attach($elementA);
$objectStructure->attach($elementB);

$visitor = new ConcreteVisitor();
$objectStructure->accept($visitor);

在上面的示例中,我们给出了一个访问者模式的示例实现。其中,我们定义了抽象元素(Element)接口和具体元素A(ConcreteElementA)和具体元素B(ConcreteElementB)的实现。接着,我们定义了抽象访问者(Visitor)接口和具体访问者(ConcreteVisitor)的实现。最后,我们创建了一个对象结构(ObjectStructure),并将具体元素添加到对象结构中。通过调用对象结构的accept方法,我们可以让访问者访问对象结构中的元素,并执行相应的操作。

通过使用访问者模式,我们可以在不修改元素类的情况下,定义新的操作或行为。访问者模式还可以帮助我们将相似的操作封装到一个访问者对象中,提高代码的复用性和可维护性。

php 设计模式
Theme Jasmine by Kent Liao