我将为您提供一个完整的Java访问者模式案例,以一个动物园系统为例进行演示。

访问者模式案例:动物园管理系统
定义元素接口(动物)
// 元素接口
public interface Animal {
void accept(Visitor visitor);
String getName();
}
具体元素(各种动物)
// 具体元素 - 狮子
public class Lion implements Animal {
private String name = "狮子";
private int weight = 190; // 体重(公斤)
private boolean isAggressive = true;
@Override
public void accept(Visitor visitor) {
visitor.visitLion(this);
}
@Override
public String getName() {
return name;
}
public void roar() {
System.out.println("狮子在咆哮!");
}
public int getWeight() {
return weight;
}
public boolean isAggressive() {
return isAggressive;
}
}
// 具体元素 - 熊猫
public class Panda implements Animal {
private String name = "熊猫";
private int bambooConsumption = 15; // 竹子消耗量(公斤/天)
private boolean isEndangered = true;
@Override
public void accept(Visitor visitor) {
visitor.visitPanda(this);
}
@Override
public String getName() {
return name;
}
public void eatBamboo() {
System.out.println("熊猫吃竹子中...");
}
public int getBambooConsumption() {
return bambooConsumption;
}
public boolean isEndangered() {
return isEndangered;
}
}
// 具体元素 - 猴子
public class Monkey implements Animal {
private String name = "猴子";
private int bananaCount = 10; // 香蕉数量
private boolean isPlayful = true;
@Override
public void accept(Visitor visitor) {
visitor.visitMonkey(this);
}
@Override
public String getName() {
return name;
}
public void climb() {
System.out.println("猴子在爬树!");
}
public int getBananaCount() {
return bananaCount;
}
public boolean isPlayful() {
return isPlayful;
}
}
访问者接口
// 访问者接口
public interface Visitor {
void visitLion(Lion lion);
void visitPanda(Panda panda);
void visitMonkey(Monkey monkey);
}
具体访问者
// 具体访问者 - 兽医
public class Veterinarian implements Visitor {
@Override
public void visitLion(Lion lion) {
System.out.println("兽医正在检查" + lion.getName() + "...");
lion.roar();
System.out.println(" 体重: " + lion.getWeight() + "kg");
System.out.println(" 攻击性: " + (lion.isAggressive() ? "高" : "低"));
System.out.println(" 建议: " + (lion.getWeight() > 250 ? "需要节食" : "身体健康"));
System.out.println(" ---");
}
@Override
public void visitPanda(Panda panda) {
System.out.println("兽医正在检查" + panda.getName() + "...");
panda.eatBamboo();
System.out.println(" 每日竹子消耗: " + panda.getBambooConsumption() + "kg");
System.out.println(" 濒危物种: " + (panda.isEndangered() ? "是" : "否"));
System.out.println(" 建议: " + (panda.getBambooConsumption() > 12 ? "食量正常" : "食欲不振"));
System.out.println(" ---");
}
@Override
public void visitMonkey(Monkey monkey) {
System.out.println("兽医正在检查" + monkey.getName() + "...");
monkey.climb();
System.out.println(" 香蕉库存: " + monkey.getBananaCount() + "个");
System.out.println(" 活泼程度: " + (monkey.isPlayful() ? "非常活泼" : "安静"));
System.out.println(" 建议: " + (monkey.getBananaCount() < 5 ? "需要补充香蕉" : "食物充足"));
System.out.println(" ---");
}
}
// 具体访问者 - 饲养员
public class Keeper implements Visitor {
@Override
public void visitLion(Lion lion) {
System.out.println("饲养员正在喂养" + lion.getName() + "...");
System.out.println(" 准备食物: 10公斤牛肉");
System.out.println(" 注意事项: " + (lion.isAggressive() ? "保持安全距离" : "可以近距离观察"));
System.out.println(" ---");
}
@Override
public void visitPanda(Panda panda) {
System.out.println("饲养员正在喂养" + panda.getName() + "...");
System.out.println(" 准备食物: " + panda.getBambooConsumption() + "公斤新鲜竹子");
System.out.println(" 注意事项: " + (panda.isEndangered() ? "特殊保护措施" : "常规饲养"));
System.out.println(" ---");
}
@Override
public void visitMonkey(Monkey monkey) {
System.out.println("饲养员正在喂养" + monkey.getName() + "...");
System.out.println(" 准备食物: " + (monkey.getBananaCount() + 5) + "根香蕉");
System.out.println(" 注意事项: " + (monkey.isPlayful() ? "注意猴子抢食物" : "正常喂养"));
System.out.println(" ---");
}
}
// 具体访问者 - 游客记录员(统计访问信息)
public class VisitorRecorder implements Visitor {
private int totalAnimals = 0;
@Override
public void visitLion(Lion lion) {
totalAnimals++;
System.out.println("游客看到" + lion.getName() + "在笼子里吼叫");
}
@Override
public void visitPanda(Panda panda) {
totalAnimals++;
System.out.println("游客看到" + panda.getName() + "在吃竹子");
}
@Override
public void visitMonkey(Monkey monkey) {
totalAnimals++;
System.out.println("游客看到" + monkey.getName() + "在树上玩耍");
}
public int getTotalAnimals() {
return totalAnimals;
}
}
对象结构(动物园)
import java.util.ArrayList;
import java.util.List;
// 对象结构 - 动物园
public class Zoo {
private List<Animal> animals = new ArrayList<>();
public void addAnimal(Animal animal) {
animals.add(animal);
}
public void removeAnimal(Animal animal) {
animals.remove(animal);
}
// 让所有动物接受访问者
public void accept(Visitor visitor) {
for (Animal animal : animals) {
animal.accept(visitor);
}
}
}
测试类
public class VisitorPatternDemo {
public static void main(String[] args) {
System.out.println("========== 动物园管理系统 ==========");
// 创建动物园
Zoo zoo = new Zoo();
// 添加动物
zoo.addAnimal(new Lion());
zoo.addAnimal(new Panda());
zoo.addAnimal(new Monkey());
// 兽医进行定期检查
System.out.println("\n【兽医检查】");
Veterinarian vet = new Veterinarian();
zoo.accept(vet);
// 饲养员进行喂养
System.out.println("\n【饲养员喂养】");
Keeper keeper = new Keeper();
zoo.accept(keeper);
// 游客记录员统计
System.out.println("\n【游客参观记录】");
VisitorRecorder recorder = new VisitorRecorder();
zoo.accept(recorder);
System.out.println("总共记录了 " + recorder.getTotalAnimals() + " 只动物");
}
}
运行结果
========== 动物园管理系统 ==========
【兽医检查】
兽医正在检查狮子...
狮子在咆哮!
体重: 190kg
攻击性: 高
建议: 身体健康
---
兽医正在检查熊猫...
熊猫吃竹子中...
每日竹子消耗: 15kg
濒危物种: 是
建议: 食量正常
---
兽医正在检查猴子...
猴子在爬树!
香蕉库存: 10个
活泼程度: 非常活泼
建议: 食物充足
---
【饲养员喂养】
饲养员正在喂养狮子...
准备食物: 10公斤牛肉
注意事项: 保持安全距离
---
饲养员正在喂养熊猫...
准备食物: 15公斤新鲜竹子
注意事项: 特殊保护措施
---
饲养员正在喂养猴子...
准备食物: 15根香蕉
注意事项: 注意猴子抢食物
---
【游客参观记录】
游客看到狮子在笼子里吼叫
游客看到熊猫在吃竹子
游客看到猴子在树上玩耍
总共记录了 3 只动物
访问者模式的优点和适用场景
优点:
- 开闭原则:新增访问者(如清洁工、表演训练师等)时,无需修改已有动物类
- 统一操作:将相关操作集中在一个访问者中,便于管理
- 解耦:允许在不修改对象结构的情况下添加新功能
适用场景:
- 一个对象结构包含多个类对象,需要对这些对象实施一些与具体类无关的操作
- 需要对一个对象结构中的对象进行很多不同并且不相关的操作
- 对象结构很少改变,但经常需要在此结构上定义新的操作
缺点:
- 增加新元素类(动物类型)时需要修改所有访问者(违反开闭原则)
- 破坏了封装性,访问者需要知道元素内部细节
这个案例展示了访问者模式如何在不同场景(医疗、喂养、记录)下,对同一组动物对象进行不同的操作,每个操作都被封装在独立的访问者类中。