访问者模式


图片转载自

cpp 复制代码
#include<iostream>
using namespace std;
#include<list>
/*模板工厂单例化,所有的商品被注册进工厂中*/
/*访问者模式(行为型模式)
访问者,被访问者
visit   accept
让访问变成一种操作,不同的访问操作有具体的实现,但是无需修改源代码(准确点说,是无需修改被访问者的源代码)
只需要增加新的具体访问类即可。局部的符合开闭原则,只是访问者类需要进行扩展和少量修改
在vitst方法中以被访问者作为参数,方法体是被访问者调用accept方法
*/
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;//观察者的名字
};

class Customer :public Vistor
{

	void visit(Apple* apple)
	{
		cout << "顾客" << _name << "挑选苹果" << endl;
	}
	void visit(Book* book)
	{
		cout << "顾客" << _name << "买书"<<endl;
	}
};

class Saler :public Vistor
{
	void visit(Apple* apple)
	{
		cout << "收银员" << _name << "称苹果" << endl;
	}
	void visit(Book* book)
	{
		cout << "收银员" << _name << "计算书价" << endl;
	}
};

class Product
{
public:
	virtual void accept(Vistor* vistor) = 0;
};

class Apple :public Product
{
public:
	void accept(Vistor* vistor)override
	{
		vistor->visit(this);
	}
};

class Book :public Product
{
public:
	void accept(Vistor* vistor)override//在具体的被访问者类中的accept方法,参数都是访问者的父类
	{
		vistor->visit(this);
	}
};

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;
};

int main()
{
	Book book;
	Apple apple;
	ShoppingCart basket;

	basket.addProduct(&book);
	basket.addProduct(&apple);

	Customer customer1;
	customer1.set_name("小明");
	basket.accept(&customer1);

	Saler saler;
	saler.set_name("小米");
	basket.accept(&saler);
	return 0;
}

这个示例代码写得一般,重点理解上面那张图:访问者模式就是在新增一个visitor类,visitor的visit方法定义参数为物品的抽象父类,同时在accepter中增加accept方法,accept方法参数为visitor,这样当具体访问者,调用其visit方法,方法体为accepter.accept()。

可以看到在保证accepter的数据结构不发生变化的情况下(没有新增或者删除),可以非常方便增加新的一种访问方法,只需要新增加一个访问类即可,但是如果我们数据结构发生变化之后,就需要修改继承自Visitor类的所有类了,这也违背了开闭原则,因此我们应该认真考虑,到底我们的数据结构是定死的还是经常变化的。没有任何一种设计模式是十全十美的,总是有所取舍,有所利弊,根据实际情况来选择才是最好的设计方法。

相关推荐
java_cj3 天前
从kubectl学Visitor模式:如何优雅处理多态数据结构的遍历
云原生·golang·k8s·访问者模式
qq_297574676 天前
设计模式系列文章(基础篇第22篇):访问者模式——分离数据结构与操作,实现灵活扩展
数据结构·设计模式·访问者模式
2601_9611940216 天前
考研模拟卷谁的比较好|27李林合工大肖四肖八数学英语408PDF
考研·elasticsearch·全文检索·代理模式·lucene·桥接模式·访问者模式
雪度娃娃23 天前
行为型设计模式——访问者模式
设计模式·访问者模式
多加点辣也没关系1 个月前
设计模式-访问者模式
设计模式·访问者模式
承渊政道1 个月前
极空间NAS部署Photopea:私有在线修图工作站,手机平板随时编辑
安全·docker·容器·ip·访问者模式·photoshop·持续部署
ximu_polaris1 个月前
设计模式(C++)-行为型模式-访问者模式
c++·设计模式·访问者模式
geovindu2 个月前
go: Visitor Pattern
开发语言·设计模式·golang·访问者模式
砍光二叉树3 个月前
【设计模式】行为型-访问者模式
设计模式·访问者模式
蜜獾云3 个月前
设计模式之访问者模式:动态的给目标对象增加新功能
设计模式·访问者模式