目的
訪問者模式可以讓你將物件操作外包給其他物件,
這樣做的最主要原因就是關注(資料結構和資料操作)分離,但是被訪問的類必須定一個契約接受訪問者, (詳見例子中 Role::accept 方法)
契約可以是一個抽象類也可以就是一個介面,在此情況下,每個訪問者必須自行選擇呼叫訪問者的哪個方法,
UML圖

★官方PHP高級學習交流社群「點擊」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限于:分布式架構、高可擴展、高性能、高并發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨
代碼
- RoleVisitorInterface.php
<?php
namespace DesignPatterns\Behavioral\Visitor;
/**
* 注意:訪問者不能自行選擇呼叫哪個方法,
* 它是由 Visitee 決定的,
*/
interface RoleVisitorInterface
{
public function visitUser(User $role);
public function visitGroup(Group $role);
}
- RoleVisitor.php
<?php
namespace DesignPatterns\Behavioral\Visitor;
class RoleVisitor implements RoleVisitorInterface
{
/**
* @var Role[]
*/
private $visited = [];
public function visitGroup(Group $role)
{
$this->visited[] = $role;
}
public function visitUser(User $role)
{
$this->visited[] = $role;
}
/**
* @return Role[]
*/
public function getVisited(): array
{
return $this->visited;
}
}
- Role.php
<?php
namespace DesignPatterns\Behavioral\Visitor;
interface Role
{
public function accept(RoleVisitorInterface $visitor);
}
- User.php
<?php
namespace DesignPatterns\Behavioral\Visitor;
class User implements Role
{
/**
* @var string
*/
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName(): string
{
return sprintf('User %s', $this->name);
}
public function accept(RoleVisitorInterface $visitor)
{
$visitor->visitUser($this);
}
}
- Group.php
<?php
namespace DesignPatterns\Behavioral\Visitor;
class Group implements Role
{
/**
* @var string
*/
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName(): string
{
return sprintf('Group: %s', $this->name);
}
public function accept(RoleVisitorInterface $visitor)
{
$visitor->visitGroup($this);
}
}
測驗
- Tests/VisitorTest.php
<?php
namespace DesignPatterns\Tests\Visitor\Tests;
use DesignPatterns\Behavioral\Visitor;
use PHPUnit\Framework\TestCase;
class VisitorTest extends TestCase
{
/**
* @var Visitor\RoleVisitor
*/
private $visitor;
protected function setUp()
{
$this->visitor = new Visitor\RoleVisitor();
}
public function provideRoles()
{
return [
[new Visitor\User('Dominik')],
[new Visitor\Group('Administrators')],
];
}
/**
* @dataProvider provideRoles
*
* @param Visitor\Role $role
*/
public function testVisitSomeRole(Visitor\Role $role)
{
$role->accept($this->visitor);
$this->assertSame($role, $this->visitor->getVisited()[0]);
}
}
PHP 互聯網架構師成長之路*「設計模式」終極指南
PHP 互聯網架構師 50K 成長指南+行業問題解決總綱(持續更新)
面試10家公司,識訓9個offer,2020年PHP 面試問題
★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術咨詢和指導,歡迎加入我們的群啊,暗號:phpzh
2020年最新PHP進階教程,全系列!

內容不錯的話希望大家支持鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什么問題 建議 想看的內容可以在評論提出
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/104286.html
標籤:其他
