概述
当我们存在一些固定的元素组合,而有一些针对这些元素的访问者,每个访问者针对不同的元素有不同的处理,这时候就可以采用访问者模式。例如,电影院在放映三场电影,有很多观众回去看,并且给予不同的评价,这里三场电影就是固定元素,观众就是访问者;再比如,系统的某个模块收到了一些固定的数据,有不同的模块需要访问并进行不同的处理,这里数据就是固定元素,不同模块是访问者。
代码实现
class Element {
public:
explicit Element(std::string name) : name_(name) {}
virtual ~Element() = default;
std::string GetName() { return name_; }
virtual void SomeOperation() = 0;
protected:
std::string name_;
};
class Element_1 : public Element {
public:
explicit Element_1(std::string name) : Element(name) {}
void SomeOperation() override {
std::cout << "Hi, I'm element 1." << std::endl;
}
};
class Element_2 : public Element {
public:
explicit Element_2(std::string name) : Element(name) {}
void SomeOperation() override {
std::cout << "Hi, I'm element 2." << std::endl;
}
};
class Visitor {
public:
virtual void ProcessElement(Element &element) = 0;
};
class Visitor_1 : public Visitor {
public:
void ProcessElement(Element &element) override {
std::cout << "I want element 1." << std::endl;
if (element.GetName() == "element1") {
element.SomeOperation();
}
};
};
class Visitor_2 : public Visitor {
public:
void ProcessElement(Element &element) override {
std::cout << "I want element 2." << std::endl;
if (element.GetName() == "element2") {
element.SomeOperation();
}
};
};
class ElementAggregation {
public:
void Add(const Element &element) { elements_.emplace_back(element); }
void AcceptVisitor(Visitor *visitor) {
for (auto &ele : elements_) {
visitor->ProcessElement(*ele);
}
}
private:
std::vector<std::unique_ptr<Element>> elements_;
};
int main() {
ElementAggregation aggregation;
aggregation.Add(Element_1("element1"));
aggregation.Add(Element_2("element2"));
Visitor *visitor_1 = new Visitor_1();
Visitor *visitor_2 = new Visitor_2();
aggregation.AcceptVisitor(visitor_1);
aggregation.AcceptVisitor(visitor_2);
}