php 设计模式 之 访问者模式

来源:互联网 发布:平凡之路 知乎 编辑:程序博客网 时间:2024/05/17 03:53

概念:

访问者模式实际上是让外部类能够获取树形结构的每个节点的对象,对每个对象进行操作的模式, 他能让我们在不改动原有树形结构的基础上扩展功能。比如统计等等

在这种模式下,必须有的几个要素:
1: 具体的元素对象, 访问者实际要访问的位置(即节点)
2: 稳定的树形结构, 每个节点都是一个元素对象, 一般在组合模式下比较多, 他提供了让访问者能够进行访问的实际位置(即访问者访问的是具体的树形结构的某个节点的实例化对象):
3: 访问者接口,这里定义了访问者的接口方法 , 这是个在每个节点都会用到的方法,用以节点处引用访问者,从而使得访问者能够访问当前节点
4: 访问者的具体实现. 继承了访问者接口,以实现接口方法
(还可以加一个要素: 元素的接口,对应 要点1)

情景:

要给不同用户组的用户添加不同的积分。

实现:

//定义元素接口abstract class User{    public function getPoint()    {        return rand();  //该数据应该由数据库中读取,这里就直接模拟某个值了    }    //这里的accept方法用于把访问者引入,在这个方法里,($visitor)访问者可以通过User类获取需要的数据进而进行相应的操作    abstract function accept(UserVisitor $vitor);}//实现元素接口class VipUser extends User{    //这里的getPoint()具体实现就由接口中实现了    //在这里就把当前对象传递给了visitor 访问者, 在访问者类的visitVip方法中就能根据$this获取必要的数据进行相应的操作    public function accept(UserVisitor $vitor)    {        $vitor->visitVip($this);    }}class NormalUser extends User{    //同上的getPoint()具体实现就由接口中实现了   //同VipUser类中的accept    public function accept(UserVisitor $vitor)    {        $vitor->visitNormal($this);    }}//定义访问者接口abstract class UserVisitor{    //访问者必须要实现的访问不同用户的接口方法    abstract function visitVip(User $user);    abstract function visitNormal(User $user);}//积分操作的访问者实现class PointActVisitor extends UserVisitor{    public function visitVip(User $user)    {        echo 'Vip用户+10分 </br>';    }    public function visitNormal(User $user)    {        echo 'Normal用户+5分</br>';    }}//用户的树形结构class Users{    protected $users;    public function addUser(User $user)    {        $this->users[] = $user;    }    //让所有的用户都能被访问者访问    public function handleVisitor(UserVisitor  $visitor)    {        foreach($this->users as $user)        {            $user->accept($visitor);        }    }}$pointVisitor = new PointActVisitor();$users = new Users();$users->addUser(new VipUser());  //添加新用户$users->addUser(new NormalUser());$users->addUser(new NormalUser());$users->handleVisitor($pointVisitor); //执行PointActVisitor访问者的操作

结果:

Vip用户+10分 Normal用户+5分Normal用户+5分
0 0
原创粉丝点击