访问者模式能够让你将对象操做外包给其余对象。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数据结构
内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出并发