php 访问者模式,访问者模式(Visitor)

本文介绍了访问者模式,其主要目的是为了分离数据结构与数据操作,通过让被访问的类定义一个契约来接受访问者。在给定的例子中,Role类需要实现accept方法以允许RoleVisitor的访问。RoleVisitor接口规定了访问用户和组的方法,而Role的实现如User和Group则决定调用哪个具体方法。测试用例验证了访问者正确地访问并记录了Role对象。
摘要由CSDN通过智能技术生成

3.12.1. 目的

访问者模式可以让你将对象操作外包给其他对象。这样做的最主要原因就是关注(数据结构和数据操作)分离。但是被访问的类必须定一个契约接受访问者。 (详见例子中的 Role::accept 方法)

契约可以是一个抽象类也可直接就是一个接口。在此情况下,每个访问者必须自行选择调用访问者的哪个方法。

3.12.2. UML 类图

7b4f1b52c155c6275d68d8879e8a3d6d.png

3.12.3. 代码

你可以在 GitHub 上找到这些代码

RoleVisitorInterface.php

namespace DesignPatterns\Behavioral\Visitor;

/**

* 注意:访问者不能自行选择调用哪个方法,

* 它是由 Visitee 决定的。

*/

interface RoleVisitorInterface

{

public function visitUser(User $role);

public function visitGroup(Group $role);

}

RoleVisitor.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

namespace DesignPatterns\Behavioral\Visitor;

interface Role

{

public function accept(RoleVisitorInterface $visitor);

}

User.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

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);

}

}

3.12.4. 测试

Tests/VisitorTest.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]);

}

}

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值