访问者模式的关键在于访问二字,在学习迭代器模式的时候,遍历就是访问的一般形式。
访问者模式的意图在于:将数据结构与作用于结构上的操作进行解耦,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作(方式:增加一个新的具体访问者就好了)。
访问者模式有两个角色,一个是被访问者,一个是访问者,在被访问者中的构造函数里有一个参数对象是访问者。
//抽象访问者,定义访问者可以做的事情 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));
}
}