访问者模式
亦称: Visitor
1. 简介
访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。它允许你在不改变对象结构的前提下(或者你不希望改变对象的结构),定义作用于这些对象元素的新操作。可以理解访问者模式把数据结构和作用于结构上的操作分离开,进行解耦。
访问者模式主要包含以下几个角色:
- Element(元素):定义一个接受访问者的方法accept,其参数为访问者对象。
- ConcreteElement(具体元素):实现accept方法,调用访问者的对应访问方法。
- Visitor(访问者):定义对每一个元素(Element)访问的行为,每个行为对应一个具体元素的访问操作。
- ConcreteVisitor(具体访问者):实现访问者定义的操作,每个操作针对不同类型的元素有不同的处理逻辑。
- ObjectStructure(对象结构):可以遍历结构中的所有元素,提供让访问者访问元素的接口。
2. 模拟场景
在电商系统中,不想频繁修改商品对象里面的属性结构,想将具体属性计算操作分离开。
java
public interface Visitor {
void visit(Product product);
}
java
// ConcreteVisitor 实现类
public class DiscountVisitor implements Visitor {
private double discount;
public DiscountVisitor(double discount) {
this.discount = discount;
}
@Override
public void visit(Product product) {
BigDecimal price = product.getPrice();
// 计算折扣后价格
BigDecimal discountedPrice = price.multiply(BigDecimal.valueOf(discount));
System.out.println(product.getName() + " 的折扣价格为:" + discountedPrice);
}
}
java
// ConcreteVisitor 实现类
public class PointVisitor implements Visitor {
private double pointRate;
public PointVisitor(double pointRate) {
this.pointRate = pointRate;
}
@Override
public void visit(Product product) {
BigDecimal price = product.getPrice();
// 计算积分
BigDecimal point = price.multiply(BigDecimal.valueOf(pointRate));
System.out.println(product.getName() + " 的折扣积分为:" + point);
}
}
java
// ConcreteElement 实现类
// 具体元素类,实现了 accept 方法,用于接受访问者的访问
public class Product {
private String name;
private Double weight;
private BigDecimal price;
public Product(String name, Double weight, BigDecimal price) {
this.name = name;
this.weight = weight;
this.price = price;
}
....// get set方法
public void accept(Visitor visitor) {
// 把自己传给访问者
visitor.visit(this);
}
}
java
public class VisitorPatternDemo {
public static void main(String[] args) {
Product laptop = new Product("电脑", 1000.0, new BigDecimal("10000.00"));
DiscountVisitor discountVisitor = new DiscountVisitor(0.8);
PointVisitor pointVisitor = new PointVisitor(0.1);
// 计算折扣和积分
laptop.accept(discountVisitor);
laptop.accept(pointVisitor);
}
}
运行结果:
3. 解决方案
4. Java中的类
- javax.lang.model.element.AnnotationValue和AnnotationValueVisitor
- javax.lang.model.element.Element和ElementVisitor
- javax.lang.model.type.TypeMirror和TypeVisitor
- java.nio.file.FileVisitor和SimpleFileVisitor
- javax.faces.component.visit.VisitContext和VisitCallback