An in-depth analysis of the visitor pattern in PHP

青灯夜游
Release: 2023-04-10 13:54:02
forward
2045 people have browsed it

In the previous article "What is the state mode in PHP? Learn it through examples"We introduced the state pattern in PHP. The following article will take you to understand the visitor pattern in PHP design patterns.

An in-depth analysis of the visitor pattern in PHP

Visitors, just like when we visit other people’s homes, or when others come to our home to visit us. Each of us is like an entity, and everyone who visits greets us one by one. After all, our Chinese nation is a nation that pays great attention to etiquette and hospitality. Visitor is the most complex pattern among GoF's 23 design patterns, and it is also the pattern that is placed last in various design pattern textbooks. Regardless of the difficulty, let's first look at its definition and implementation.

Gof class diagram and explanation

GoF definition: Represents an operation that acts on each element in an object structure. It allows you to define new operations that act on each element without changing its class

GoF Class Diagram

An in-depth analysis of the visitor pattern in PHP

Code implementation

interface Visitor
{
    public function VisitConcreteElementA(ConcreteElementA $a);
    function VisitConcreteElementB(ConcreteElementB $b);
}

class ConcreteVisitor1 implements Visitor
{
    public function VisitConcreteElementA(ConcreteElementA $a)
    {
        echo get_class($a) . "被" . get_class($this) . "访问", PHP_EOL;
    }
    public function VisitConcreteElementB(ConcreteElementB $b)
    {
        echo get_class($b) . "被" . get_class($this) . "访问", PHP_EOL;
    }
}

class ConcreteVisitor2 implements Visitor
{
    public function VisitConcreteElementA(ConcreteElementA $a)
    {
        echo get_class($a) . "被" . get_class($this) . "访问", PHP_EOL;
    }
    public function VisitConcreteElementB(ConcreteElementB $b)
    {
        echo get_class($b) . "被" . get_class($this) . "访问", PHP_EOL;
    }
}
Copy after login

Abstract visitor interface and two specific implementations. It can be regarded as a young couple visiting our home!

interface Element
{
    public function Accept(Visitor $v);
}

class ConcreteElementA implements Element
{
    public function Accept(Visitor $v)
    {
        $v->VisitConcreteElementA($this);
    }
    public function OperationA()
    {

    }
}

class ConcreteElementB implements Element
{
    public function Accept(Visitor $v)
    {
        $v->VisitConcreteElementB($this);
    }
    public function OperationB()
    {

    }
}
Copy after login

Element abstraction and implementation can also be regarded as entities to be accessed. Of course it’s me and my wife.

class ObjectStructure
{
    private $elements = [];

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

    public function Detach(Element $element)
    {
        $position = 0;
        foreach ($this->elements as $e) {
            if ($e == $element) {
                unset($this->elements[$position]);
                break;
            }
            $position++;
        }
    }

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

}
Copy after login

This is an object structure used to save element entities and make access calls. Everyone met in the living room and exchanged greetings. This is just a living room.

$o = new ObjectStructure();
$o->Attach(new ConcreteElementA());
$o->Attach(new ConcreteElementB());

$v1 = new ConcreteVisitor1();
$v2 = new ConcreteVisitor2();

$o->Accept($v1);
$o->Accept($v2);
Copy after login

The call of the client finally allowed everyone to meet formally and introduce each other and shake hands. One visit was completed happily.

  • Let visitors call the specified element. It should be noted here that the behavior of visitors calling elements is generally fixed and rarely changes. That is, the two methods VisitConcreteElementA() and VisitConcreteElementB(). That is to say, the class that defines the object structure rarely changes, but when it is often necessary to define new operations on this structure, the visitor pattern is used.
  • It is necessary to perform many different and unrelated operations on the objects in an object structure. When you want to avoid having these operations "pollute" the classes of these objects, the visitor pattern is suitable
  • The visitor pattern is suitable for situations where the data structure does not change. Therefore, it is a mode that you cannot use normally, but you can only use this mode when needed. GoF: "Most of the time you don't need visitor mode, but when you do, you really need it." Because there are few situations where the data structure does not change
  • Some advantages and disadvantages of the visitor pattern: easy to add new operations; concentrate related operations and separate irrelevant operations; it is difficult to add new ConcreteElement classes; through Access at class level; accumulate status; destroy encapsulation

Our company’s accounts only have two items (Element): income and expenditure, but different departments (Visitor) will give produce different content. For example, when I check, I only need to check the monthly or quarterly summary data. The financial director needs detailed income and expenditure records, and the accountant needs complete details when doing accounting. It can be seen that the operation of the company really requires a very wide range of knowledge, not only management capabilities, but also accounting knowledge is necessary to understand! !

Full code: https://github.com/zhangyue0503/designpatterns-php/blob/master/23.visitor/source/visitor.php

Example

The last example of the pattern is back to our message sending. The same applies to multiple service providers. As visitors, they need to use their own SMS sending and APP push interfaces. At this time, you can use the visitor mode to operate and realize all the operations of these visitors.

Visitor mode information sending

An in-depth analysis of the visitor pattern in PHP

Full source code: https://github.com/zhangyue0503/designpatterns- php/blob/master/23.visitor/source/visitor-msg.php

<?php

interface ServiceVisitor
{
    public function SendMsg(SendMessage $s);
    function PushMsg(PushMessage $p);
}

class AliYun implements ServiceVisitor
{
    public function SendMsg(SendMessage $s)
    {
        echo &#39;阿里云发送短信!&#39;, PHP_EOL;
    }
    public function PushMsg(PushMessage $p)
    {
        echo &#39;阿里云推送信息!&#39;, PHP_EOL;
    }
}

class JiGuang implements ServiceVisitor
{
    public function SendMsg(SendMessage $s)
    {
        echo &#39;极光发送短信!&#39;, PHP_EOL;
    }
    public function PushMsg(PushMessage $p)
    {
        echo &#39;极光推送短信!&#39;, PHP_EOL;
    }
}

interface Message
{
    public function Msg(ServiceVisitor $v);
}

class PushMessage implements Message
{
    public function Msg(ServiceVisitor $v)
    {
        echo &#39;推送脚本启动:&#39;;
        $v->PushMsg($this);
    }
}

class SendMessage implements Message
{
    public function Msg(ServiceVisitor $v)
    {
        echo &#39;短信脚本启动:&#39;;
        $v->SendMsg($this);
    }
}

class ObjectStructure
{
    private $elements = [];

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

    public function Detach(Message $element)
    {
        $position = 0;
        foreach ($this->elements as $e) {
            if ($e == $element) {
                unset($this->elements[$position]);
                break;
            }
            $position++;
        }
    }

    public function Accept(ServiceVisitor $visitor)
    {
        foreach ($this->elements as $e) {
            $e->Msg($visitor);
        }
    }

}

$o = new ObjectStructure();
$o->Attach(new PushMessage());
$o->Attach(new SendMessage());

$v1 = new AliYun();
$v2 = new JiGuang();

$o->Accept($v1);
$o->Accept($v2);
Copy after login

Description

  • We assume sending SMS and sending push They are two unchanged behaviors, that is, their data structures are stable and unchanged
  • This way we can easily add ServiceVisitor. When adding Baidu Cloud or other SMS providers, it will be very easy Just add visitors conveniently
  • The visitor mode is more suitable for structures with stable data structures. For example, bills only have income and expenses, people’s gender is only male and female, etc.

Original address: https://juejin.cn/post/6844903993240453133

Author: Hardcore Project Manager

recommends learning: "PHP Video Tutorial"

The above is the detailed content of An in-depth analysis of the visitor pattern in PHP. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!