【编程素质】设计模式-访问者模式(Visitor Pattern)

1,概念

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

把数据结构和作用于结构上的操作之间解耦,使得操作集合可以相对自由地演化。

1)访问者角色(Visitor):可扩展的。

声明了一个或者多个访问操作,也就是说,该访问者需要做哪些操作;

2)节点角色(Element):固定不变的。

也就是Water这个接口的,它声明一个接受操作,接受一个访问者对象作为一个参量,也就是说,当访问者到来时,需要怎么做。

2,场景

具体操作能够非常稳定的情景下,能够很容易的拓展访问者(Visitor)。eg:JSqlParser框架、stream遍历(内部迭代)。

  1. 对于一个Visitor,它需要有什么操作,必须要非常清楚;改动成本非常大,如果有新的步骤加入,作为一个导游菜单增强Visitor类。
    如下文的例子,招待客人只有茶、咖啡、果汁这3个材料,如果需要增加啤酒就需要增加一个节点类和water实现类,还得在Visitor中加入一个方法,改动所有的Visitor的实现类。
  2. 增加新的访问者那就非常的简单
    多来一个客人,也就是新增加一个新Visitor实现类。

3,UML图

在这里插入图片描述

4, 实现

请客人喝茶,每个人口味不同,提前准备好物料。每来一个客人,就抽象一个Visitor的具体实现。

//基本的访问者操作
public interface Visitor {
    void visit(TeaWater teaWater);
    void visit(JuiceWater juiceWater);
    void visit(CaffeeWater caffeeWater);
}
//要喝的东西
public interface Water {
    void accept(Visitor visitor);
}
//具体的水:茶、咖啡、果汁,不同类型的水也许会有各自的一些属性操作等等。
public class TeaWater implements Water {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
 
    public String getHotTea(){
        return "热茶";
    }
    public String getColdTea(){
        return "凉茶";
    }
}
public class CaffeeWater implements Water {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
 
    public void addSugar(int number){
        System.out.print("添加了"+number+"勺糖");
    } 
}
public class JuiceWater implements Water {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    public String getJuice(int size){
        return  size==0?"小杯":"大杯";
    }
}

两个访问者:张三李四。定义visitor的偏好。

public class ZhangsanVisitor implements Visitor{
 
    @Override
    public void visit(TeaWater teaWater) {
 
        System.out.print("张三只喝茶,");
        String hotTea = teaWater.getHotTea();
        System.out.println("拿了"+hotTea);
    }
 
    @Override
    public void visit(JuiceWater juiceWater) {
        //不喜欢果汁,什么操作也不做
    }
    @Override
    public void visit(CaffeeWater caffeeWater) {
        //不喜欢咖啡,
    }
}
public class LisiVisitor implements Visitor {
    @Override
    public void visit(TeaWater teaWater) {
        System.out.print("能喝点茶");
        String coldTea = teaWater.getColdTea();
        System.out.println(",拿了"+coldTea);
    } 
    @Override
    public void visit(JuiceWater juiceWater) {
        System.out.print("也能喝果汁");
        String juice = juiceWater.getJuice(1);
        System.out.println(",还是要"+juice);
    } 
    @Override
    public void visit(CaffeeWater caffeeWater) { 
        System.out.print("咖啡也要喝,");
        caffeeWater.addSugar(2);
    }
}
//准备桌子,关联water和visiter
public class Table {
    //准备好所有要喝的东西
    List waters = new ArrayList<>();
 
    public void addWater(Water water){
        waters.add(water);
    }
    //招待客人
    public void accept(Visitor visitor){
        for (Water water : waters){
            water.accept(visitor);
        }
    }
}
//具体的使用
@Test
    public void test01(){
        Table table = new Table();
        table.addWater(new TeaWater());//摆上茶
        table.addWater(new JuiceWater()); //摆上果汁
        table.addWater(new CaffeeWater()); //摆上咖啡
 
 
        Visitor zhangsan = new ZhangsanVisitor();
        Visitor lisi = new LisiVisitor();
        System.out.println("张三");
        table.accept(zhangsan);
        System.out.println("李四");
        table.accept(lisi);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值