访问者模式

发布时间 2023-12-18 17:33:02作者: 求简君

访问者模式的关键在于访问二字,在学习迭代器模式的时候,遍历就是访问的一般形式。

访问者模式的意图在于:将数据结构与作用于结构上的操作进行解耦,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作(方式:增加一个新的具体访问者就好了)。

访问者模式有两个角色,一个是被访问者,一个是访问者,在被访问者中的构造函数里有一个参数对象是访问者。

//抽象访问者,定义访问者可以做的事情
public interface CustomerVisitor {

 String browseProducts(Goods goods); //浏览商品
 
}


//抽象元素,包含接受操作,被访问者作为accept
public abstract class Goods {

 private String name; //商品名称
 
 private Integer price; //商品价格
 
 abstract Integer accept(CustomerVisitor visitor); //接收访问者
 
 public Goods(){
  
 }
 
 public Goods(String name,Integer price){
  this.name = name;
  this.price = price;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }

 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }

 /**
  * @return the price
  */
 public Integer getPrice() {
  return price;
 }

 /**
  * @param price the price to set
  */
 public void setPrice(Integer price) {
  this.price = price;
 }

 @Override
 public String toString() {
  return this.name+"价格:"+this.price;
 }
 
}


//具体访问者-普通会员
public class OrdinaryVisitor implements CustomerVisitor{

 @Override
 public String browseProducts(Goods goods) {
  String goodsMessage = goods.toString();
  return goodsMessage;
 }

}

//具体访问者-VIP会员
public class VipVisitor implements CustomerVisitor{

 @Override
 public String browseProducts(Goods goods) {
  goods.setPrice(goods.getPrice()-5);
  String goodsMessage = goods.toString();
  return goodsMessage;
 }

}

public class Book extends Goods{

 public Book(String name,Integer price){
  super(name, price);
 }
 
 /**
  * 接受访问者,并且把自已(商品)传给访问者
  */
 @Override
 Integer accept(CustomerVisitor visitor) {
  String bp = visitor.browseProducts(this); //把一些处理逻辑(计算费用)的  【操作权限】  给访问者
  System.out.println(bp); //打印浏览价格
  return this.getPrice();
 }

}


/对象结构角色
public class ShoppingCartStructure {

 private List<Goods> list = new ArrayList<Goods>();
 
 /**
  * 计算总价
  */
 public String accept(CustomerVisitor visitor){
  Iterator<Goods> i = list.iterator();
        Integer price = 0;
        while (i.hasNext()) {
         price += ((Goods) i.next()).accept(visitor);
        }
  return "商品总价"+price;
  
 }
 
 /**
  * 添加商品
  */
 public void add(Goods goods) {
        list.add(goods);
    }
    public void remove(Goods goods) {
        list.remove(goods);
    }
}

public class Client {

 public static void main(String[] args) {
  Goods hlm = new Book("红楼梦",120);
  Goods sgyy = new Book("三国演义",105);
  Goods xyj = new Book("西游记",80);
  
  //创建访问者-普通会员
  OrdinaryVisitor ov = new OrdinaryVisitor();
  //创建结构对象-购物车
  ShoppingCartStructure scs = new ShoppingCartStructure();
  System.out.println("普通会员浏览商品");
  scs.add(hlm); //添加商品
  scs.add(sgyy); //添加商品
  scs.add(xyj); //添加商品
  System.out.println(scs.accept(ov));
  
  //创建访问者-VIP会员
  VipVisitor vip = new VipVisitor();
  //创建结构对象-购物车
  ShoppingCartStructure vscs = new ShoppingCartStructure();
  System.out.println("VIP会员浏览商品");
  vscs.add(hlm);
  vscs.add(sgyy);
  vscs.add(xyj);
  System.out.println(vscs.accept(vip));
  
 }
}