PHP设计模式之访问者模式(Visitor)代码实例大全(32)

目的

访问者模式能够让你将对象操做外包给其余对象。php

这样作的最主要缘由就是关注(数据结构和数据操做)分离。可是被访问的类必须定一个契约接受访问者。 (详见例子中 Role::accept 方法)laravel

契约能够是一个抽象类也能够就是一个接口。在此状况下,每一个访问者必须自行选择调用访问者的哪一个方法。面试

UML图

★官方PHP高级学习交流社群「点击」管理整理了一些资料,BAT等一线大厂进阶知识体系备好(相关学习资料以及笔面试题)以及不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货sql

代码

  • 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 互联网架构师成长之路*「设计模式」终极指南shell

PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)设计模式

面试10家公司,收获9个offer,2020年PHP 面试问题服务器

★若是喜欢个人文章,想与更多资深开发者一块儿交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入咱们的群啊,暗号:phpzh数据结构

2020年最新PHP进阶教程,全系列!架构

内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出并发