设计模式有23种之多,要想记住这二十多种模式的确不太容易,但是如果将模式的名字与典型的场景结合起来可能会更容易记忆。对于访问者模式,一个典型的例子就是不同的游客(visitor)游览一个地方不同的景区。
访问者模式的意图是将易变的操作和稳定的数据结构分离开。文本典型的例子中,一个地方的景区基本上是稳定不变的,而对不同游客所做的优惠活动则会有很多不同的类型,比如学生游客,教师游客,老年游客,外国游客,抗疫志愿者游客等等。
public interface Visitor {
void visitSummerPalace(SummerPalace summerPalace);
void visitTheGreatWall(TheGreatWall theGreatWall);
}
public class StudentVisitor implements Visitor {
@Override
public void visitSummerPalace(SummerPalace summerPalace) {
double v = summerPalace.ticketRate() * 0.5;
System.out.println("half price to visit SummerPalace for students. # The price is $" + v);
}
@Override
public void visitTheGreatWall(TheGreatWall theGreatWall) {
double v = theGreatWall.ticketRate() * 0.5;
System.out.println("half price to visit The Great Wall for students. # The price is $" + v);
}
}
public class FightCovidHeroVisitor implements Visitor {
@Override
public void visitSummerPalace(SummerPalace summerPalace) {
double v = summerPalace.ticketRate() * 0.0;
System.out.println("free to visit SummerPalace for fighting Convid-19 heroes. # The price is $" + v);
}
@Override
public void visitTheGreatWall(TheGreatWall theGreatWall) {
double v = theGreatWall.ticketRate() * 0.0;
System.out.println("free to visit The Great Wall for fighting Convid-19 heroes. The price is $" + v);
}
}
public interface ScenerySpot {
void accept(Visitor visitor);
int ticketRate();
}
public class SummerPalace implements ScenerySpot {
@Override
public void accept(Visitor visitor) {
visitor.visitSummerPalace(this);
}
@Override
public int ticketRate() {
return 120;
}
}
public class TheGreatWall implements ScenerySpot {
@Override
public void accept(Visitor visitor) {
visitor.visitTheGreatWall(this);
}
@Override
public int ticketRate() {
return 100;
}
}
public class BeijingTourismCenter {
private Set<ScenerySpot> scenerySpotSet = new HashSet<>();
public void accept(Visitor visitor) {
for (ScenerySpot spot : scenerySpotSet)
spot.accept(visitor);
}
public void add(ScenerySpot spot) {
scenerySpotSet.add(spot);
}
public void remove(ScenerySpot spot) {
scenerySpotSet.remove(spot);
}
}
public class Client {
public static void main(String[] args) {
BeijingTourismCenter tourismCenter = new BeijingTourismCenter();
tourismCenter.add(new SummerPalace());
tourismCenter.add(new TheGreatWall());
// add more...
tourismCenter.accept(new FightCovidHeroVisitor());
System.out.println("----------------------------");
tourismCenter.accept(new StudentVisitor());
// accept more...
}
}
free to visit SummerPalace for fighting Convid-19 heroes. # The price is $0.0
free to visit The Great Wall for fighting Convid-19 heroes. The price is $0.0
----------------------------
half price to visit SummerPalace for students. # The price is $60.0
half price to visit The Great Wall for students. # The price is $50.0
Process finished with exit code 0
访问者模式包含一个 Double dispatch (双分派)的概念。
spot.accept(visitor);
spot 是动态绑定的,visitor 也是动态绑定的。
- https://www.runoob.com/design-pattern/visitor-pattern.html
- https://www.baeldung.com/java-visitor-pattern
- https://cloud.tencent.com/developer/article/1755832
原型模式(Prototype Pattern)
抽象工厂模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
工厂模式(Factory Pattern)
单例模式(Singleton Pattern)
助记语:原抽建工单
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
适配器模式(Adapter Pattern)
外观模式(Facade Pattern)
过滤器模式(Filter/Criteria Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
助记语:想呆室外,过桥组装
责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
中介者模式(Mediator Pattern)
迭代器模式(Iterator Pattern)
观察者模式(Observer Pattern)
策略模式(Strategy Pattern)
状态模式(State Pattern)
备忘录模式(Memento Pattern)
模板方法模式(Template Pattern)
访问者模式(Visitor Pattern)
助记语:责令解中谍,观测状被模仿