📅  最后修改于: 2023-12-03 14:57:40.612000             🧑  作者: Mango
访问者设计模式是一种行为型设计模式,它可以将算法与复杂的数据结构进行分离。在访问者模式中,我们可以定义一个新的操作(也称为访问者),并将其应用于一个对象的元素结构中,而不需要修改对象的类。
访问者设计模式的四个角色:
下面是访问者设计模式的类图:
假设我们有一个网站上有各种商品的页面,我们要给每个商品计算折扣价,并给出折扣后的价格。我们可以使用访问者设计模式来实现这个需求。
首先,我们定义一个访问者接口 Visitor
,其中有两个方法,分别用于计算普通商品和折扣商品的价格。
public interface Visitor {
double visitNormalProduct(NormalProduct normalProduct);
double visitDiscountProduct(DiscountProduct discountProduct);
}
然后,我们定义两种商品,分别是普通商品和折扣商品,它们都实现了 Element
接口中的 accept
方法,用于将访问者对象传递进来并执行对应的操作。
public interface Element {
double accept(Visitor visitor);
}
public class NormalProduct implements Element {
private String name;
private double price;
public NormalProduct(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
@Override
public double accept(Visitor visitor) {
return visitor.visitNormalProduct(this);
}
}
public class DiscountProduct implements Element {
private String name;
private double discount;
private double originPrice;
public DiscountProduct(String name, double discount, double originPrice) {
this.name = name;
this.discount = discount;
this.originPrice = originPrice;
}
public String getName() {
return name;
}
public double getDiscount() {
return discount;
}
public double getOriginPrice() {
return originPrice;
}
@Override
public double accept(Visitor visitor) {
return visitor.visitDiscountProduct(this);
}
}
最后,我们定义两个具体访问者,分别是普通产品价格计算器和折扣产品价格计算器,它们实现了 Visitor
接口中的方法,并按照具体的算法来计算对应的价格。
public class NormalProductPriceCalculator implements Visitor {
@Override
public double visitNormalProduct(NormalProduct normalProduct) {
return normalProduct.getPrice();
}
@Override
public double visitDiscountProduct(DiscountProduct discountProduct) {
return discountProduct.getOriginPrice() * discountProduct.getDiscount();
}
}
public class DiscountProductPriceCalculator implements Visitor {
@Override
public double visitNormalProduct(NormalProduct normalProduct) {
return normalProduct.getPrice() * 0.9;
}
@Override
public double visitDiscountProduct(DiscountProduct discountProduct) {
return discountProduct.getOriginPrice() * discountProduct.getDiscount() * 0.8;
}
}
最终,我们可以像下面这样使用访问者设计模式:
Element[] elements = {new NormalProduct("电视机", 2999),
new DiscountProduct("苹果手机", 0.8, 5999),
new DiscountProduct("华为笔记本电脑", 0.75, 8999)};
Visitor normalCalculator = new NormalProductPriceCalculator();
Visitor discountCalculator = new DiscountProductPriceCalculator();
double totalPrice1 = 0;
for (Element element : elements) {
totalPrice1 += element.accept(normalCalculator);
}
System.out.println("普通商品原价总价:" + totalPrice1);
double totalPrice2 = 0;
for (Element element : elements) {
totalPrice2 += element.accept(discountCalculator);
}
System.out.println("折扣商品折扣价总价:" + totalPrice2);
输出结果为:
普通商品原价总价:11997.0
折扣商品折扣价总价:9898.400000000001
我们可以看到,访问者设计模式让计算器与商品具体的实现分离,使得程序更加可扩展和易维护。
访问者设计模式是一种非常有用的设计模式,可以将算法与数据结构进行分离,使得代码更加可扩展和易于维护。它的核心要点在于访问者接口的定义和访问者的具体实现,通过这些可以将具体的算法和数据结构进行分离。在使用访问者设计模式时需要考虑合理的类设计和继承关系,以及良好的代码风格和命名规范。