设计模式学习(十九) 访问者模式 Visitor

1.访问者模式的定义

 访问者模式的官方定义,就是表示一个作用于某对象结构的各元素的操作,它使你可以在不改变各元素的前提下,定义作用于这些元素的操作。这句话的意思就是,将对象结构这一块的数据结构Element作为一个整体,通过一个结构对象ObjectStructure封装起来;同时访问者Visitor定义一个抽象类,在其内部定义针对这块数据结构中每种结构的执行方式,其通过ObjectStructure的高级接口,实现对这一块所有/部分数据结构进行访问。而根据对访问者Visitor抽象类的实例方式不同,对于这些数据结构元素Element的操作方式也不尽相同。
 所以总结来说,数据结构元素Element类中提供进行操作的接口,而访问者Visitor中定义对于不同元素Element类的操作接口,不同的访问者Visitor实例类的实现方式不同,则对于同种Element元素类的操作方式自然也就不同了。

2.访问者模式的类图

访问者模式类图
 通过类图可知,访问者模式中,客户端Client可调用的类仅为Visitor访问者类,以及ObjectStructure结构对象类。其中,访问者类Visitor中定义了所有具体元素类ConcreteElement的接口,其通过子类ConcreteVisitor来实现接口的实例化操作,并由此实现子类对于不同ConcreteElement元素类的不同操作;而ObjectStructure结构对象类为一个高级类,其内部封装了所有的ConcreteElement元素类,从而实现对于所有元素的增删使用等操作功能。具体如下:

  1. Visitor访问者类:这是一个抽象类,针对所需访问的所有ConcreteElement实例类均提供了对应的接口;
  2. ConcreteVisitor实例类:其继承自Visitor访问者类,用于实现其定义的对于所有ConcreteElement实例元素类的访问接口,由于不同ConcreteVisitor实例类的实现方式不同,从而使得不同访问者对于ConcreteElement实例元素类的访问权限也不相同;
  3. Element元素类:这是一个抽象类,其中定义了用于接受访问者Visitor的接口Accept;
  4. ConcreteElement元素实例类:其继承自Element元素类,用于实现其定义的接口Accept,该接口的实现通常为调用访问者Visitor的接口中,对应当前ConcreteElement元素实例类的接口。同时,其中仍可以加入诸如获取时间,获取访问者姓名的等功能;
  5. ObjectStructure结构对象类:其内部可以存储一个或多个Element元素类,并在其内部定义高级接口,实现对于Element元素类的增删、使用等功能;
  6. Client客户端:其定义具体的访问者,并使用ObjectStructure结构对象类,在ObjectStructure结构对象类中调用所需使用的Element元素类,使用客户端所定义的访问者类对其进行访问。

3.访问者模式的代码实现

 本例中选用了一个Restaurant作为ObjectStructure结构对象类,其内部有多种RestaurantPart作为Element元素类,其中具体的ConcreteElement元素实例类为饭店中的大厅Hall、厨房Kitchen以及办公室Office。而访问者类Visitor为典型定义,其ConcreteVisitor实例类对应的是饭店的顾客Guest、厨师Cook以及经理Manager。
 对于本例的实际操作,即定义三种类型(顾客Guest、厨师Cook以及经理Manager)的访问者Visitor,与分为三种类型(大厅Hall、厨房Kitchen以及办公室Office)的五个元素,将元素定义完成后存入结构对象类(Restaurant)中,通过调用Restaurant中的AccepAll接口,实现所有顾客对饭店中所有元素的访问尝试。

#include <iostream>
#include <map>
#include <string>
using namespace std;

class Visitor;
class Hall;
class Kitchen;
class Office;

class RestaurantPart
{
public:
	RestaurantPart(string name) : m_name(name) {}
	string getName() { return m_name; }
	virtual void Accept(Visitor *) = 0;
protected:
	string m_name;
};

class Visitor
{
public:
	Visitor(string name) : m_name(name) {}
	virtual void VisitHall(Hall* systempart) = 0;
	virtual void VisitKitchen(Kitchen* systempart) = 0;
	virtual void VisitOffice(Office* systempart) = 0;
	string getName() { return m_name; }
protected:
	string m_name;
};

class Hall : public RestaurantPart
{
public:
	Hall(string name) : RestaurantPart(name){}
	void Accept(Visitor *visitor)
	{
		cout << "visitor " << visitor->getName() << " trying to visit the Hall named " << m_name << endl;
		visitor->VisitHall(this);
	}
};

class Kitchen : public RestaurantPart
{
public:
	Kitchen(string name) : RestaurantPart(name) {}
	void Accept(Visitor *visitor)
	{
		cout << "visitor " << visitor->getName() << " trying to visit the Kitchen named " << m_name << endl;
		visitor->VisitKitchen(this);
	}
};

class Office : public RestaurantPart
{
public:
	Office(string name) : RestaurantPart(name) {}
	void Accept(Visitor *visitor)
	{
		cout << "visitor " << visitor->getName() << " trying to visit the Office named " << m_name << endl;
		visitor->VisitOffice(this);
	}
};

class Guest : public Visitor
{
public:
	Guest(string name) : Visitor(name) {}
	void VisitHall(Hall* systempart) override
	{
		cout << "Welcome to visit the Hall named " << systempart->getName() << endl;
	}
	void VisitKitchen(Kitchen* systempart) override
	{
		cout << "Sorry! " << m_name << " can't enter the Kitchen named " << systempart->getName() << endl;
	}
	void VisitOffice(Office* systempart) override
	{
		cout << "Sorry! " << m_name << " can't enter the Office named " << systempart->getName() << endl;
	}
};

class Cook : public Visitor
{
public:
	Cook(string name) : Visitor(name) {}
	void VisitHall(Hall* systempart) override
	{
		cout << "Welcome to visit the Hall named " << systempart->getName() << endl;
	}
	void VisitKitchen(Kitchen* systempart) override
	{
		cout << "Welcome to visit the Kitchen named " << systempart->getName() << endl;
	}
	void VisitOffice(Office* systempart) override
	{
		cout << "Sorry! " << m_name << " can't enter the Office named " << systempart->getName() << endl;
	}
};

class Manager : public Visitor
{
public:
	Manager(string name) : Visitor(name) {}
	void VisitHall(Hall* systempart) override
	{
		cout << "Welcome to visit the Hall named " << systempart->getName() << endl;
	}
	void VisitKitchen(Kitchen* systempart) override
	{
		cout << "Welcome to visit the Kitchen named " << systempart->getName() << endl;
	}
	void VisitOffice(Office* systempart) override
	{
		cout << "Welcome to visit the Office named " << systempart->getName() << endl;
	}
};

class Restaurant
{
public:
	Restaurant() { m_restaurantpart_list.clear(); }
	void insert(RestaurantPart* restaurantpart)
	{
		m_restaurantpart_list.insert({ restaurantpart->getName(),restaurantpart });
	}
	void remove(RestaurantPart* restaurantpart)
	{
		m_restaurantpart_list.erase(restaurantpart->getName());
	}
	RestaurantPart* use(string name)
	{
		return m_restaurantpart_list.at(name);
	}
	void AcceptAll(Visitor* vistor)
	{
		for (auto &s : m_restaurantpart_list)
			s.second->Accept(vistor);
	}
private:
	map<string, RestaurantPart*> m_restaurantpart_list;
};

int main()
{
	//1.Visitor,饭店部门,饭店的定义与赋值
	Visitor* GuestMike = new Guest("GuestMike");
	Visitor* CookJack = new Cook("CookJack");
	Visitor* ManagerLinda = new Manager("ManagerLinda");

	RestaurantPart* FirstHall = new Hall("FirstHall");
	RestaurantPart* SecondHall = new Hall("SecondHall");
	RestaurantPart* FirstKitchen = new Kitchen("FirstKitchen");
	RestaurantPart* SecondKitchen = new Kitchen("SecondKitchen");
	RestaurantPart* BossOffice = new Office("BossOffice");

	Restaurant* CrisCloseDoor = new Restaurant;
	CrisCloseDoor->insert(FirstHall);
	CrisCloseDoor->insert(SecondHall);
	CrisCloseDoor->insert(FirstKitchen);
	CrisCloseDoor->insert(SecondKitchen);
	CrisCloseDoor->insert(BossOffice);

	//2.测试
	cout << "***** GuestMike 全部访问 *****" << endl;
	CrisCloseDoor->AcceptAll(GuestMike);
	cout << "***** CookJack 全部访问 *****" << endl;
	CrisCloseDoor->AcceptAll(CookJack);
	cout << "***** ManagerLinda 全部访问 *****" << endl;
	CrisCloseDoor->AcceptAll(ManagerLinda);

	delete GuestMike;
	delete CookJack;
	delete ManagerLinda;
	delete FirstHall;
	delete SecondHall;
	delete FirstKitchen;
	delete SecondKitchen;
	delete BossOffice;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
设计模式中的访问者模式Visitor Pattern)是一种行为型模式,它允许你在不修改对象结构的情况下定义新的操作。访问者模式通过将操作封装在访问者对象中,使得可以在不改变被访问对象的类的前提下,定义新的操作。 访问者模式的参与者包括: - 抽象接口(Glaph):定义了需要操纵对象的抽象接口。 - 具体实现类(Character):实现了抽象接口,并接受访问者的访问和操作。 - 访问者抽象类(Visitor):定义了访问者的缺省方法。 - 具体访问者(ConcreteVisitor):实现了访问者抽象类,对需要增加的操作进行实现。 Java中的实际应用举例可以以ASM技术为例。ASM是一个Java字节码操纵框架,它可以用来动态生成、修改和分析Java字节码。在ASM中,访问者模式被广泛应用于字节码的访问和操作。 以下是一个使用访问者模式的Java代码示例: ```java // 抽象接口 public interface Acceptable { void accept(Visitor visitor); } // 具体实现类 public class Character implements Acceptable { @Override public void accept(Visitor visitor) { visitor.visit(this); } } // 访问者抽象类 public abstract class Visitor { public abstract void visit(Character character); } // 具体访问者 public class ConcreteVisitor extends Visitor { @Override public void visit(Character character) { // 对Character进行操作 } } // 使用访问者模式 public class Main { public static void main(String[] args) { Character character = new Character(); Visitor visitor = new ConcreteVisitor(); character.accept(visitor); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值