访问者模式(Visitor),表示一个作用于某对象结构中的各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
Visitor.h:
#ifndef VISTOR_H_
#define VISTOR_H_
#include
class Apple;
class Book;
// 抽象访问者
class Vistor {
public:
void set_name(std::string name) {
name_ = name;
}
virtual void visit(Apple *apple) = 0;
virtual void visit(Book *book) = 0;
protected:
std::string name_;
};
#endif // VISTOR_H_
Element.h:
#ifndef ELEMENT_H_
#define ELEMENT_H_
#include "Visitor.h"
// 抽象元素类
class Product {
public:
virtual void accept(Vistor *vistor) = 0;
};
#endif // ELEMENT_H_
ConcreteVisitor.h:
#ifndef CONCRETE_VISTOR_H_
#define CONCRETE_VISTOR_H_
#include
#include "Visitor.h"
// 具体访问者类: 顾客
class Customer : public Vistor {
public:
void visit(Apple *apple) {
std::cout << "顾客" << name_ << "挑选苹果。" << std::endl;
}
void visit(Book *book) {
std::cout << "顾客" << name_ << "买书。" << std::endl;
}
};
// 具体访问者类: 收银员
class Saler : public Vistor {
public:
void visit(Apple *apple) {
std::cout << "收银员" << name_ << "给苹果过称, 然后计算价格。" << std::endl;
}
void visit(Book *book) {
std::cout << "收银员" << name_ << "计算书的价格。" << std::endl;
}
};
#endif // CONCRETE_VISTOR_H_
ConcreteElement.h:
#ifndef CONCRETE_ELEMENT_H_
#define CONCRETE_ELEMENT_H_
#include "Element.h"
// 具体产品类: 苹果
class Apple : public Product {
public:
void accept(Vistor *vistor) override {
vistor->visit(this);
}
};
// 具体产品类: 书籍
class Book : public Product {
public:
void accept(Vistor *vistor) override {
vistor->visit(this);
}
};
#endif // CONCRETE_ELEMENT_H_
Client.h:
#ifndef CLIENT_H_
#define CLIENT_H_
#include
#include "Visitor.h"
#include "Element.h"
// 购物车
class ShoppingCart {
public:
void accept(Vistor *vistor) {
for (auto prd : prd_list_) {
prd->accept(vistor);
}
}
void addProduct(Product *product) {
prd_list_.push_back(product);
}
void removeProduct(Product *product) {
prd_list_.remove(product);
}
private:
std::list<Product*> prd_list_;
};
#endif // CLIENT_H_
main.cpp:
#include "Client.h"
#include "ConcreteElement.h"
#include "ConcreteVisitor.h"
int main() {
system("chcp 65001");
Book book;
Apple apple;
ShoppingCart basket;
basket.addProduct(&book);
basket.addProduct(&apple);
Customer customer;
customer.set_name("小张");
basket.accept(&customer);
Saler saler;
saler.set_name("小杨");
basket.accept(&saler);
system("pause");
return 0;
}
输出:
Active code page: 65001
顾客小张买书。
顾客小张挑选苹果。
收银员小杨计算书的价格。
收银员小杨给苹果过称, 然后计算价格。
Press any key to continue . . .