概念
访问者模式将数据结构与数据操作分离,我们使用了一个访问者类,它改变了元素类的执行算法。根据不同的访问者,可以执行不同的执行逻辑。
实现
案例:这次我们来到了玛丽莲梦路,这条路上有两家饭店,分别是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