Home > Article > Backend Development > An in-depth analysis of the visitor pattern in PHP
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.
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 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
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; } }
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() { } }
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); } } }
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);
The call of the client finally allowed everyone to meet formally and introduce each other and shake hands. One visit was completed happily.
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
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
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 '阿里云发送短信!', PHP_EOL; } public function PushMsg(PushMessage $p) { echo '阿里云推送信息!', PHP_EOL; } } class JiGuang implements ServiceVisitor { public function SendMsg(SendMessage $s) { echo '极光发送短信!', PHP_EOL; } public function PushMsg(PushMessage $p) { echo '极光推送短信!', PHP_EOL; } } interface Message { public function Msg(ServiceVisitor $v); } class PushMessage implements Message { public function Msg(ServiceVisitor $v) { echo '推送脚本启动:'; $v->PushMsg($this); } } class SendMessage implements Message { public function Msg(ServiceVisitor $v) { echo '短信脚本启动:'; $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);
Description
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!