首页 > 代码库 > Design Pattern Visitor 访问者设计模式

Design Pattern Visitor 访问者设计模式

访问者设计模式是已经有了一组Person对象了,然后不同的访问者访问这组对象,会有不同效果。

这些访问者实际上就是一个可以让Person对象组执行的动作行为等。

至于这些Person对象是如何执行这些访问者的动作的,那是已经在特定的不同的Person对象中设计好的。

比如我们的访问者也许是一些动作集合的类,如:

class Action
{
public:
	string present;
	string gun;
	virtual void drinkBeer(Person *p) = 0;
	virtual void getAGun(Person *p) = 0;
};

根据这个访问者基类定义不同的访问动作:

class ActionOne:public Action
{
public:
	ActionOne()
	{
		present = "Alcohol";
		gun = "Laiser";
	}
	void drinkBeer(Person *p);
	void getAGun(Person *p);
};

class ActionTwo:public Action
{
public:
	ActionTwo()
	{
		present = "Beer";
		gun = "Machine Gun";
	}
	void getAGun(Person *p);
	void drinkBeer(Person *p);
};

而Person类则执行动作类的不同动作,也是基类动作的一部分,这样呈现出不同Person执行的行为不一样。

class Person
{	
public:
	string something;
	virtual void receivedVisitor(Action *visitor) = 0;
};

class Bill:public Person
{
public:
	Bill()
	{
		something = "food";
	}
	void receivedVisitor(Action *visitor)
	{
		puts("\nVisitor to Bill bring :");
		puts(visitor->present.c_str());
		visitor->drinkBeer(this);
	}
};

class Mark:public Person
{
public:
	Mark()
	{
		something = "Weapon";
	}
	void receivedVisitor(Action *visitor)
	{
		puts("\nVisitor to Mark bring :");
		puts(visitor->gun.c_str());
		visitor->getAGun(this);
	}
};

使用一个类来存放这些对象:

class House
{
protected:
	vector<Person *> vps;
public:
	void addPerson(Person *p)
	{
		vps.push_back(p);
	}
	void receiver(Action *visitor)
	{
		for (int i = 0; i < (int)vps.size(); i++)
		{
			vps[i]->receivedVisitor(visitor);
		}
	}
	~House()
	{
		for (int i = 0; i < (int)vps.size(); i++)
		{
			delete vps[i];
		}
	}
};

最后就在这个类对象中存放需要被访问的对象,然后使用动作类来访问这些对象。

总的来说也是思想并不太难的一个设计模式,但是要很好实现还是不太容易的。


全部代码如下:

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Person;

class Action
{
public:
	string present;
	string gun;
	virtual void drinkBeer(Person *p) = 0;
	virtual void getAGun(Person *p) = 0;
};

class ActionOne:public Action
{
public:
	ActionOne()
	{
		present = "Alcohol";
		gun = "Laiser";
	}
	void drinkBeer(Person *p);
	void getAGun(Person *p);
};

class ActionTwo:public Action
{
public:
	ActionTwo()
	{
		present = "Beer";
		gun = "Machine Gun";
	}
	void getAGun(Person *p);
	void drinkBeer(Person *p);
};

class Person
{	
public:
	string something;
	virtual void receivedVisitor(Action *visitor) = 0;
};

class Bill:public Person
{
public:
	Bill()
	{
		something = "food";
	}
	void receivedVisitor(Action *visitor)
	{
		puts("\nVisitor to Bill bring :");
		puts(visitor->present.c_str());
		visitor->drinkBeer(this);
	}
};

class Mark:public Person
{
public:
	Mark()
	{
		something = "Weapon";
	}
	void receivedVisitor(Action *visitor)
	{
		puts("\nVisitor to Mark bring :");
		puts(visitor->gun.c_str());
		visitor->getAGun(this);
	}
};

void ActionOne::drinkBeer(Person *p)
{
	puts("Let's eat something");
	puts(p->something.c_str());
}

void ActionOne::getAGun(Person *p)
{
	puts("Let's gear up");
	puts(p->something.c_str());
}

void ActionTwo::getAGun(Person *p)
{
	puts("Let's gear up");
	puts(p->something.c_str());
}

void ActionTwo::drinkBeer(Person *p)
{
	puts("Let's eat something");
	puts(p->something.c_str());
}

class House
{
protected:
	vector<Person *> vps;
public:
	void addPerson(Person *p)
	{
		vps.push_back(p);
	}
	void receiver(Action *visitor)
	{
		for (int i = 0; i < (int)vps.size(); i++)
		{
			vps[i]->receivedVisitor(visitor);
		}
	}
	~House()
	{
		for (int i = 0; i < (int)vps.size(); i++)
		{
			delete vps[i];
		}
	}
};

int main()
{
	House house;
	house.addPerson(new Bill);
	house.addPerson(new Mark);
	ActionTwo gun;
	ActionOne drink;
	house.receiver(&gun);
	house.receiver(&drink);
	return 0;
}

执行: