3.12. Visitor
The contract is an abstract class but you can have also a cleaninterface. In that case, each Visitor has to choose itself which methodto invoke on the visitor.
RoleVisitorInterface.php
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;
- }
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\Tests\Visitor\Tests;
- 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]);
- }