访问者模式-Visitor(Java实现)
访问者模式-Visitor
对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同。在这种场景下就可以使用访问者模式了.
对于本文中的一组对象Archer(弓箭手) Rider(骑兵) Gunner(火枪手) 这一组对象, 由不同的访问者(AttackVisitor 和 RetreatVisitor)访问, 产生的结果会不同. 一种是进攻, 一种是撤退.
本例子中的类关系图如下所示:

Soldier是士兵接口. 本例子中实现了三种"士兵".
本例子中有两个visitor. 分别用来处理
加上依赖关系后如下图所示:

被作用对象
Soldier接口
public interface Soldier {
void accept(Visitor v);
}
Archer类
public class Archer implements Soldier {
@Override
public void accept(Visitor v) {
v.visit(this);
}
public String getArcher() {
return "Archer";
}
}
Gunner类
public class Gunner implements Soldier {
@Override
public void accept(Visitor v) {
v.visit(this);
}
public String getGunner() {
return "Gunner";
}
}
Rider类
public class Rider implements Soldier {
@Override
public void accept(Visitor v) {
v.visit(this);
}
public String getRider() {
return "Rider";
}
}
访问者
Visitor接口
public interface Visitor {
void visit(Gunner gunner);
void visit(Rider rider);
void visit(Archer archer);
}
AttackVisitor类
public class AttackVisitor implements Visitor {
@Override
public void visit(Gunner gunner) {
System.out.println(gunner.getGunner() + " 发起进攻");
}
@Override
public void visit(Rider rider) {
System.out.println(rider.getRider() + " 发起进攻");
}
@Override
public void visit(Archer archer) {
System.out.println(archer.getArcher() + " 发起进攻");
}
}
RetreatVisitor类
public class RetreatVisitor implements Visitor {
@Override
public void visit(Gunner gunner) {
System.out.println(gunner.getGunner() + " 开始撤退");
}
@Override
public void visit(Rider rider) {
System.out.println(rider.getRider() + " 开始撤退");
}
@Override
public void visit(Archer archer) {
System.out.println(archer.getArcher() + " 开始撤退");
}
}
Main
运行调试
public class Main {
public static void main(String[] args) {
Soldier[] list = {new Gunner(), new Rider(), new Archer()};
RetreatVisitor retreat = new RetreatVisitor();
AttackVisitor attack = new AttackVisitor();
for (Soldier element : list) {
element.accept(attack);
}
System.out.println();
for (Soldier element : list) {
element.accept(retreat);
}
}
}
结果如下:

总结
在Visitor模式中, 可以很轻松地添加一个Visitor. 比如本文例子中的. 进攻有AttackVisitor, 撤退有RetreatVisitor.
如果想再加一种Visitor呢?
比如在古代, 士兵们都是"战时打仗,闲时种地", 想再加一个FarmVisitor.
很简单啊, 只需要单独增加这个FarmVisitor就可以了, 不需要进行其他的修改. 这样就可以遍历所有的士兵, 用FarmVisitor来让所有的士兵们进行耕地了.
但是.如果在Visitor模式中, 想再加新的一种士兵怎么办呢?
就比如想再加一种刺客兵种 Assassin.
那可就麻烦了...现有的所有的Visitor都只支持Rider, Gunner 和 Archer. 都不支持Assassin.
所有就要给每个Visitor都新添一个方法, 让他们支持Assassin这个兵种.
Visitor模式的目的就是将 `处理` 从 `数据结构` 中分离出来. 如果把具体的调用写在了各个士兵类里面, 那么当扩展新功能的时候, 就需要修改这些士兵类.
而如果用了Visitor模式, 增加一个新功能, 就只需要增加一个Visitor就好了.
学如不及,犹恐失之

浙公网安备 33010602011771号