小白谈谈访问者模式

概念

访问者模式将数据结构与数据操作分离,我们使用了一个访问者类,它改变了元素类的执行算法。根据不同的访问者,可以执行不同的执行逻辑。

实现

案例:这次我们来到了玛丽莲梦路,这条路上有两家饭店,分别是ctb饭店,小明饭店,通常饭店都是有人进去光顾,光顾也是访问的一种形式,我们这次讲访问者模式就用访问来代替吧。不同的人进去饭店,可能需求不一样,作为消费者,我们选择饭店是看点评的,作为卫生部门,是通过检查饭店的卫生情况进行登记。
好了,说了这么多,直接上代码:

首先我们定义一个饭店的抽象类:

public abstract class Restaurant {

    //接收访问者访问
    public abstract void accept(Visitor_ visitor_);

    //获取点评
    public abstract int getEvaluation();

    //获取清洁度
    public abstract int getClean();
}

然后就是对这个抽象类进行实例化,上文也提到,有两家饭店:

public class CtbRestaurant extends Restaurant {

    Random random = new Random();
    private int evaluation = random.nextInt(10);
    private int clean = random.nextInt(10);

    @Override
    public void accept(Visitor_ visitor_) {
        visitor_.visit(this);
    }

    // 获取大众评价
    @Override
    public int getEvaluation(){
        return evaluation;
    }

    // 获取卫生情况
    @Override
    public int getClean(){
        return clean;
    }
}
public class XiaoMingRestaurant extends Restaurant {

    Random random = new Random();
    private int evaluation = random.nextInt(10);
    private int clean = random.nextInt(10);

    @Override
    public void accept(Visitor_ visitor_) {
        visitor_.visit(this);
    }

    // 获取大众评价
    @Override
    public int getEvaluation(){
        return evaluation;
    }

    // 获取卫生情况
    @Override
    public int getClean(){
        return clean;
    }
}

我们还需要定义一个访问者的接口

public interface Visitor_ {

    //进行访问
    void visit(Restaurant restaurant);
}

有接口,就得有实现,上文中也提到了,我们有消费者和政府部门

/**
 * 定义消费者的类,消费者访问主要查看饭店的评价
 */
public class Customer implements Visitor_ {

    @Override
    public void visit(Restaurant restaurant) {
        System.out.println(restaurant.getEvaluation());
    }
}
/**
 * 定义政府部门的类,政府部门访问主要查看饭店的卫生情况
 */
public class Government implements Visitor_ {
    @Override
    public void visit(Restaurant restaurant) {
        System.out.println(restaurant.getClean());
    }
}

有了两家饭店,我们得知道这两家饭店在哪里啊,那就得定义一个路:

public class Road {

    private CtbRestaurant ctbRestaurant;
    private XiaoMingRestaurant xiaoMingRestaurant;

    public Road() {
        ctbRestaurant = new CtbRestaurant();
        xiaoMingRestaurant = new XiaoMingRestaurant();
    }

    //在这条路上,供访问者进行访问
    public void visit(Visitor_ visitor_){
        ctbRestaurant.accept(visitor_);
        xiaoMingRestaurant.accept(visitor_);
    }
}

最后就是测试了:

public class Main {

    public static void main(String[] args) {

        //先实例这条路
        Road road = new Road();

        //消费者进行访问
        System.out.println("两家店的点评分别为:");
        road.visit(new Customer());

        System.out.println("-------------------------------");

        //政府部门进行访问
        System.out.println("两家店的卫生水平为:");
        road.visit(new Government());
    }
}

测试结果:
在这里插入图片描述

优点:各角色职责分离,符合单一职责原则,具有良好的扩展性,使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化

缺点:具体元素对访问者公布细节,违反了迪米特原则,具体元素变更时导致修改成本大,违反了依赖倒置原则,为了达到“区别对待”而依赖了具体类,没有以来抽象


参考:https://www.jianshu.com/p/1f1049d0a0f4
本文的代码:https://pan.baidu.com/s/1QSNeAolzNfSvlijfWuO9hQ
提取码:kkve

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值