24.访问器模式

#include <iostream>
#include <vector>

// 定义一个抽象的动物类
class Animal {
public:
    virtual ~Animal() {}
};

// 定义具体的动物类,继承自动物类
class Lion : public Animal {};
class Tiger : public Animal {};
class Panda : public Animal {};

// 定义一个抽象的访问者类,声明对不同动物的访问方法
class Visitor {
public:
    virtual void visit(Lion* lion) = 0;
    virtual void visit(Tiger* tiger) = 0;
    virtual void visit(Panda* panda) = 0;
    virtual ~Visitor() {}
};

// 定义具体的访问者类,继承自访问者类,实现对不同动物的访问方法
class Feeder : public Visitor {
public:
    void visit(Lion* lion) override {
        std::cout << "Feeding the lion with meat.\n";
    }
    void visit(Tiger* tiger) override {
        std::cout << "Feeding the tiger with meat.\n";
    }
    void visit(Panda* panda) override {
        std::cout << "Feeding the panda with bamboo.\n";
    }
};

class Observer : public Visitor {
public:
    void visit(Lion* lion) override {
        std::cout << "Observing the lion's behavior.\n";
    }
    void visit(Tiger* tiger) override {
        std::cout << "Observing the tiger's behavior.\n";
    }
    void visit(Panda* panda) override {
        std::cout << "Observing the panda's behavior.\n";
    }
};

class Photographer : public Visitor {
public:
    void visit(Lion* lion) override {
        std::cout << "Taking a photo of the lion.\n";
    }
    void visit(Tiger* tiger) override {
        std::cout << "Taking a photo of the tiger.\n";
    }
    void visit(Panda* panda) override {
        std::cout << "Taking a photo of the panda.\n";
    }
};

// 定义一个动物园类,包含一个动物的集合,并提供一个接受访问者的方法
class Zoo {
private:
    std::vector<Animal*> animals;
public:
    // 添加一个动物到集合中
    void addAnimal(Animal* animal) {
        animals.push_back(animal);
    }

    // 接受一个访问者,并让它遍历集合中的每个动物,并根据动态类型调用相应的访问方法
    void accept(Visitor* visitor) {
        for (auto animal : animals) { 
            if (auto lion = dynamic_cast<Lion*>(animal)) {
                visitor->visit(lion);
            }
            else if (auto tiger = dynamic_cast<Tiger*>(animal)) {
                visitor->visit(tiger);
            }
            else if (auto panda = dynamic_cast<Panda*>(animal)) {
                visitor->visit(panda);
            }
        }
    }

    // 析构函数,释放动物的内存
    ~Zoo() {
        for (auto animal : animals) {
            delete animal;   
        }
    }
};

// 测试代码
int main() {
    // 创建一个动物园对象,并添加一些动物
    Zoo zoo;
    zoo.addAnimal(new Lion());
    zoo.addAnimal(new Tiger());
    zoo.addAnimal(new Panda());

    // 创建一些访问者对象,并让它们访问动物园
    Feeder feeder;
    Observer observer;
    Photographer photographer;

    zoo.accept(&feeder);
    zoo.accept(&observer);
    zoo.accept(&photographer);

} 

假设你有一个游戏平台,里面有很多种类的游戏,比如免费游戏和收费游戏。这些游戏就是数据结构中的元素。 你也有很多种类的玩家,比如免费玩家和付费玩家。这些玩家就是造访者。 不同的玩家访问不同的游戏,会有不同的效果。比如免费玩家只能玩免费游戏,付费玩家可以玩所有的游戏。这些效果就是操作。 如果你不使用造访者模式,那么你需要在每个游戏类中定义一个方法,来判断玩家是否可以访问这个游戏。这样会使得游戏类变得复杂,而且每当你增加一个新的玩家类型或者新的游戏类型时,你都需要修改所有的游戏类,增加新的方法。这样会很麻烦,而且容易出错。 如果你使用造访者模式,那么你只需要在每个游戏类中定义一个方法,来接受一个玩家作为参数。然后在每个玩家类中定义两个方法,分别对应免费游戏和收费游戏。这样,当一个玩家访问一个游戏时,就会先调用游戏的接受方法,然后再调用玩家的访问方法。这样就可以实现不同的效果,而不需要修改游戏类。而且每当你增加一个新的玩家类型或者新的游戏类型时,你只需要增加一个新的玩家类或者新的游戏类,而不需要修改其他的类。这样就很方便,而且很灵活。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值