訪問者模式能夠讓你將對象操做外包給其餘對象。php
這樣作的最主要緣由就是關注(數據結構和數據操做)分離。可是被訪問的類必須定一個契約接受訪問者。 (詳見例子中 Role::accept 方法)laravel
契約能夠是一個抽象類也能夠就是一個接口。在此狀況下,每一個訪問者必須自行選擇調用訪問者的哪一個方法。面試
<?php namespace DesignPatterns\Behavioral\Visitor; /** * 注意:訪問者不能自行選擇調用哪一個方法, * 它是由 Visitee 決定的。 */ interface RoleVisitorInterface { public function visitUser(User $role); public function visitGroup(Group $role); }
<?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; } }
<?php namespace DesignPatterns\Behavioral\Visitor; interface Role { public function accept(RoleVisitorInterface $visitor); }
<?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); } }
<?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); } }
<?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 互聯網架構師成長之路*「設計模式」終極指南shell
PHP 互聯網架構師 50K 成長指南+行業問題解決總綱(持續更新)設計模式
面試10家公司,收穫9個offer,2020年PHP 面試問題服務器
★若是喜歡個人文章,想與更多資深開發者一塊兒交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入咱們的羣啊,暗號:phpzh數據結構
內容不錯的話但願你們支持鼓勵下點個贊/喜歡,歡迎一塊兒來交流;另外若是有什麼問題 建議 想看的內容能夠在評論提出併發