访问者模式
访问者模式的关键在于访问二字,在学习迭代器模式的时候,遍历就是访问的一般形式。
访问者模式的意图在于:将数据结构与作用于结构上的操作进行解耦,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作(方式:增加一个新的具体访问者就好了)。
访问者模式有两个角色,一个是被访问者,一个是访问者,在被访问者中的构造函数里有一个参数对象是访问者。
//抽象访问者,定义访问者可以做的事情
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));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通