前文回顾
单例模式(一)
单例模式(二)
观察者模式
简单工厂模式
工厂方法模式(一)
工厂方法模式(二)
抽象工厂模式(一)
抽象工厂模式(二)
原型模式
外观模式
中介者模式
代理模式
装饰者模式
策略模式
状态模式
命令模式
建造者模式
桥接模式
解释器模式
前言
访问者模式的本质就是想给一系列对象添加新的方法,但是又不想在原来类代码中进行增加,即保持既有的类不变,把要添加的方法再新的类中进行实现。
所谓访问者就是一系列行为的统称,通过多态实现多种行为的添加,通过函数重载实现针对不同对象的特定行为的调用。
实现举例
- 场景描述
假设动物园中只有狗和猫两种动物,开始所有动物只有一个名称属性,但预留了访问者接口,后续可以给动物增加新的行为而不用修改既有的类。 - 动物基类
#include <string>
using namespace std;
class Visitor;
class Animal
{
public:
Animal(const string &m_name):name(m_name){}
string getName() const {return name ;}
virtual ~Animal(){}
virtual void accept(Visitor *m_visitor) = 0;
protected:
string name;
};
- 动物派生类
①.Dog 类
#include "animal.h"
class Dog : public Animal
{
public:
using Animal::Animal;
void accept(Visitor *m_visitor) override;
};
#include "dog.h"
#include "visitor.h"
void Dog::accept(Visitor *m_visitor)
{
m_visitor->visit(this);
}
②.Cat 类
#include "animal.h"
class Cat : public Animal
{
public:
using Animal::Animal;
void accept(Visitor *m_visitor) override;
};
#include "cat.h"
#include "visitor.h"
void Cat::accept(Visitor *m_visitor)
{
m_visitor->visit(this);
}
- 访问者基类
#include <iostream>
class Dog;
class Cat;
class Visitor
{
public:
Visitor(){};
virtual ~Visitor(){}
virtual void visit(Dog * animal) = 0;
virtual void visit(Cat * animal) = 0;
};
- 访问者派生类
①.叫 访问者
#include "visitor.h"
class SpeakVisitor : public Visitor
{
public:
SpeakVisitor(){}
void visit(Cat *animal) override;
void visit(Dog *animal) override;
};
#include "speakvisitor.h"
#include "cat.h"
#include "dog.h"
void SpeakVisitor::visit(Cat *animal)
{
cout << animal->getName()+"叫:喵喵~"<<endl;
}
void SpeakVisitor::visit(Dog *animal)
{
cout << animal->getName()+"叫:汪汪~"<<endl;
}
②.跑 访问者
#include "visitor.h"
class RunVisitor : public Visitor
{
public:
RunVisitor(){}
void visit(Dog *animal) override;
void visit(Cat *animal) override;
};
#include "runvisitor.h"
#include "dog.h"
#include "cat.h"
void RunVisitor::visit(Dog *animal)
{
cout << animal->getName()+"跑:一蹦一蹦~"<<endl;
}
void RunVisitor::visit(Cat *animal)
{
cout << animal->getName()+"跑:一跳一跳~"<<endl;
}
- 动物园类
#include "animal.h"
#include "visitor.h"
#include <list>
#include <memory>
using namespace std;
class Zoo
{
public:
Zoo(){};
void addAnimal(shared_ptr<Animal> animal)
{
animals.push_back(animal);
}
void RemoveAnimal(shared_ptr<Animal> animal)
{
animals.remove(animal);
}
void accept(Visitor * visitor)
{
for(auto &animal:animals )
{
animal->accept(visitor);
}
}
private:
list<shared_ptr<Animal>> animals;
};
- 客户端调用
#include "dog.h"
#include "runvisitor.h"
#include "speakvisitor.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Zoo *zoo = new Zoo ();
shared_ptr<Dog> dog1(new Dog("泰迪"));
shared_ptr<Dog> dog2(new Dog("哈士奇"));
shared_ptr<Cat> cat1(new Cat("波斯猫"));
shared_ptr<Cat> cat2(new Cat("HelloKitty"));
zoo->addAnimal(dog1);
zoo->addAnimal(dog2);
zoo->addAnimal(cat1);
zoo->addAnimal(cat2);
cout << "所有动物开始叫:"<<endl;
SpeakVisitor * speak = new SpeakVisitor () ;
zoo->accept(speak);
cout << endl;
zoo->RemoveAnimal(cat1);//移除一个对象
cout << "所有动物开始跑:"<<endl;
RunVisitor * run = new RunVisitor();
zoo->accept(run);
return a.exec();
}