版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a770794164/article/details/90749948
访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
举例:
有的节假日,公司会安排员工一起去户外进行一些小游戏,每个游戏中,男女同事的任务形式也不同,比如吹气球,其中男同事需要用嘴吹,女同事用打气筒;骑自行车带人,男同事负责骑车,女同事负责坐在后面等。这个情景就可以用访问者模式来实现,男同事和女同事就是两个不同的元素,每种游戏都是一个访问者。
- 元素类
abstract class Person {
String name;
public Person(String name) {
this.name = name;
}
abstract void play(Game game);
}
// 男同事类
class ManWorkmate extends Person {
public ManWorkmate(String name) {
super(name);
}
@Override
void play(Game game) {
game.acceptManGame(this);
}
}
// 女同事类
class WomanWorkmate extends Person {
public WomanWorkmate(String name) {
super(name);
}
@Override
void play(Game game) {
game.acceptWomenManGame(this);
}
}
- 访问者,即各种游戏
abstract class Game {
abstract void acceptManGame(Person person);
abstract void acceptWomenManGame(Person person);
}
// 吹气球
class BallonGame extends Game {
@Override
void acceptManGame(Person person) {
System.out.println("男同事:" + person.name + " ,吹气球啦!");
}
@Override
void acceptWomenManGame(Person person) {
System.out.println("女同事:" + person.name + " ,用打气筒吹气球啦!");
}
}
// 骑自行车
class BikeGame extends Game {
@Override
void acceptManGame(Person person) {
System.out.println("男同事:" + person.name + " ,准备骑自行车啦!");
}
@Override
void acceptWomenManGame(Person person) {
System.out.println("女同事:" + person.name + " ,准备坐在自行车后座啦!");
}
}
- 对象结构,针对不同的游戏遍历参与游戏的同事,得到不同的反应
class ObjectStructure {
List<Person> elements = new ArrayList<>();
void add(Person person) {
elements.add(person);
}
void del(Person person) {
elements.remove(person);
}
void beginGame(Game game){
for (Person person : elements) {
person.play(game);
}
}
}
- 主程序
class Test {
public static void main(String[] args) {
ObjectStructure o = new ObjectStructure();
Person xiaoLi = new ManWorkmate("小李");
Person xiaoWang = new WomanWorkmate("小王");
Person xiaoZhang = new ManWorkmate("小张");
Person xiaoZhao = new WomanWorkmate("小赵");
o.add(xiaoLi);
o.add(xiaoWang);
o.add(xiaoZhang);
o.add(xiaoZhao);
System.out.println("进行第一项游戏:吹气球");
Game game1 = new BallonGame();
o.beginGame(game1);
System.out.println("======");
System.out.println("进行第二项游戏:骑自行车");
Game game2 = new BikeGame();
o.beginGame(game2);
}
}
结果:
进行第一项游戏:吹气球
男同事:小李 ,吹气球啦!
女同事:小王 ,用打气筒吹气球啦!
男同事:小张 ,吹气球啦!
女同事:小赵 ,用打气筒吹气球啦!
======
进行第二项游戏:骑自行车
男同事:小李 ,准备骑自行车啦!
女同事:小王 ,准备坐在自行车后座啦!
男同事:小张 ,准备骑自行车啦!
女同事:小赵 ,准备坐在自行车后座啦!
如果需要再增加游戏方式,只需要再增加一个Game
子类,在主程序中,调用
Game game3 = new OtherGame();
o.beginGame(game3);
就可以实现。
总结
访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
访问者模式的目的是要把处理从数据结构分离出来。如果一个系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就比较合适,因为访问者模式使得算法操作的增加变得容易。
访问者结构的缺点就是使增加新的数据结构变得困难了。GoF的一个作者就说过:“大多数时候你并不需要访问者模式,但当一旦你需要访问者模式时,那就是真的需要它了。”事实上,我们很难找到数据结构不变的情况,所以使用访问者模式的机会也就不太多。