设计模式之访问者

一、访问者设计模式概念

        访问者模式(Visitor) 是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。

 适用场景

  • 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
  • 可使用访问者模式来清理辅助行为的业务逻辑。
  • 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。

访问者设计模式的结构

  1. 访问者 (Visitor) 接口声明了一系列以对象结构的具体元素为参数的访问者方法。 如果编程语言支持重载, 这些方法的名称可以是相同的, 但是其参数一定是不同的。
  2. 具体访问者 (Concrete Visitor) 会为不同的具体元素类实现相同行为的几个不同版本。
  3. 元素 (Element) 接口声明了一个方法来 “接收” 访问者。 该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素 (Concrete Element) 必须实现接收方法。 该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。 请注意, 即使元素基类实现了该方法, 所有子类都必须对其进行重写并调用访问者对象中的合适方法。
  5. 客户端 (Client) 通常会作为集合或其他复杂对象 (例如一个组合 (opens new window)树) 的代表。 客户端通常不知晓所有的具体元素类, 因为它们会通过抽象接口与集合中的对象进行交互。

代码如下:

        问题:做一款生成冰激凌和雪糕的程序,要求可以扩展新的口味,并且可以扩展新的包装方式。
        解决方案:表示一个作用于某对象结构中的各元素的操作。
    它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

#include <iostream>
#include <string>
#include <vector>
class IceCream;
class Popsicle;
class Visitor
{
public:
	virtual void visitIceCream(const IceCream *iceCream)const = 0;
	virtual void visitPopsicle(const Popsicle *popsicle)const = 0;
};

class Component
{
public:
    	virtual void accept(Visitor* visitor) const = 0;
};

class IceCream : public Component
{
public:
	virtual void accept(Visitor* visitor) const
	{
		visitor->visitIceCream(this);
	}
	std::string getIceCream()const
	{
		return "冰激凌";
	}
};

class Popsicle : public Component
{
public:
	virtual void accept(Visitor* visitor) const
	{
		visitor->visitPopsicle(this);
	}
	std::string getPopsicle()const
	{
		return "雪糕";
	}
};

class Frosting : public Visitor
{
public:
	void visitIceCream(const IceCream* iceCream)const override
	{
		std::cout << iceCream->getIceCream() << " + 糖霜" << std::endl;

	}
	void visitPopsicle(const Popsicle* popsicle)const override
	{
		std::cout << popsicle->getPopsicle() << " + 糖霜" << std::endl;
	}
};

class Chocolate : public Visitor
{
public:
	void visitIceCream(const IceCream* iceCream)const override
	{
		std::cout << iceCream->getIceCream() << " + 巧克力" << std::endl;

	}
	void visitPopsicle(const Popsicle* popsicle)const override
	{
		std::cout << popsicle->getPopsicle() << " + 巧克力" << std::endl;
	}
};

void clientCode(const std::vector<Component*>& components,Visitor* visitor)
{
	for (const auto& component : components)
	{
		component->accept(visitor);
	}
}

int main()
{
	std::vector<Component*> components = { new IceCream,new Popsicle,new Popsicle };
	Frosting frosting;
	clientCode(components, &frosting);
	Chocolate chocolate;
	clientCode(components, &chocolate);
	return 0;
}

 二、与其他模式的关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值