访问者模式


图片转载自

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类的所有类了,这也违背了开闭原则,因此我们应该认真考虑,到底我们的数据结构是定死的还是经常变化的。没有任何一种设计模式是十全十美的,总是有所取舍,有所利弊,根据实际情况来选择才是最好的设计方法。

相关推荐
WangMing_X10 天前
C# 23种设计模式(4)访问者模式(Visitor Pattern)
开发语言·设计模式·c#·访问者模式
我码玄黄13 天前
JS设计模式之访问者模式
javascript·设计模式·访问者模式
博风14 天前
设计模式:24、访问者模式
设计模式·访问者模式
喵手21 天前
设计模式探秘:迭代器模式与访问者模式详解
设计模式·迭代器模式·访问者模式
橘色的喵22 天前
C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher
c++·访问者模式·观察者·cyberrt·datavisitor·datadispatcher
小白不太白9501 个月前
设计模式之 访问者模式
java·设计模式·访问者模式
蓝田~1 个月前
访问者模式
访问者模式
萨达大1 个月前
23种设计模式-访问者(Visitor)设计模式
java·c++·设计模式·软考·访问者模式·软件设计师·行为型设计模式
丶白泽2 个月前
重修设计模式-行为型-访问者模式
java·设计模式·访问者模式·1024程序员节
努力找工作的OMArmy2 个月前
软件开发----设计模式每日刷题(转载于牛客)
java·单例模式·设计模式·策略模式·访问者模式·模板方法模式·开闭原则