Java访问者案例

wen java案例 3

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

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 只动物

访问者模式的优点和适用场景

优点:

  1. 开闭原则:新增访问者(如清洁工、表演训练师等)时,无需修改已有动物类
  2. 统一操作:将相关操作集中在一个访问者中,便于管理
  3. 解耦:允许在不修改对象结构的情况下添加新功能

适用场景:

  • 一个对象结构包含多个类对象,需要对这些对象实施一些与具体类无关的操作
  • 需要对一个对象结构中的对象进行很多不同并且不相关的操作
  • 对象结构很少改变,但经常需要在此结构上定义新的操作

缺点:

  • 增加新元素类(动物类型)时需要修改所有访问者(违反开闭原则)
  • 破坏了封装性,访问者需要知道元素内部细节

这个案例展示了访问者模式如何在不同场景(医疗、喂养、记录)下,对同一组动物对象进行不同的操作,每个操作都被封装在独立的访问者类中。

抱歉,评论功能暂时关闭!