访问者
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.
实例
main.cc:
#include <windows.h>
#include "swim_action.h"
#include "bike_action.h"
#include "run_action.h"
#include "female_people.h"
#include "male_people.h"
#include "Object_structure.h"
/*
design_pattern:"visitor"
在跑团的活动中,男/女参与各种各样的活动,对于活动有各自的评价,活动类型很有可能随着时间不断添加,访问者模式,对于活动的增加扩展性极好
游泳: 男人可以看美女,女人可以秀身材
跑步: 男人觉得大汗淋淋,很舒服,女人觉得又累又无聊
骑行: 男人觉得一个人骑车,好无聊!,女生很享受沿途的风景
*/
int main(){
ObjectStructure *object = new ObjectStructure();
People *male = new MalePeople();
People *female = new FemalePeople();
Action *swim = new SwimAction();
object->Add(male);
object->Add(female);
object->FeedBack(swim);
//add bike item
Action *bike = new BikeAction();
object->FeedBack(bike);
//add run item
Action *run = new RunAction();
object->FeedBack(run);
//add ... item easy.
//clear
delete object;
delete male;
delete female;
delete swim;
delete bike;
delete run;
system("Pause");
return 0;
}
People:
//people.h
#ifndef HELENDP_SOURCE_PEOPLE_H_
#define HELENDP_SOURCE_PEOPLE_H_
#include "action.h"
class People{
public:
People();
virtual ~People();
virtual void Join(Action *action) = 0;
};
#endif
//people.cc
#include "people.h"
People::People(){
}
People::~People(){
}
FemalPeople:
//femal_people.h
#ifndef HELENDP_SOURCE_FEMALE_PEOPLE_H_
#define HELENDP_SOURCE_FEMALE_PEOPLE_H_
#include "people.h"
class FemalePeople : public People{
public:
FemalePeople();
~FemalePeople();
void Join(Action *action);
};
#endif
//femal_people.cc
#include "female_people.h"
FemalePeople::FemalePeople(){
}
FemalePeople::~FemalePeople(){
}
void FemalePeople::Join(Action *action){
action->GetFemaleFeedBack(this);
}
MalePeople:
//male_people.h
#ifndef HELENDP_SOURCE_MALE_PEOPLE_H_
#define HELENDP_SOURCE_MALE_PEOPLE_H_
#include "people.h"
class MalePeople : public People{
public:
MalePeople();
~MalePeople();
void Join(Action *action);
};
#endif
//male_people.cc
#include "male_people.h"
MalePeople::MalePeople(){
}
MalePeople::~MalePeople(){
}
void MalePeople::Join(Action *action){
action->GetMaleFeedBack(this);
}
ObjectStructure:
//object_structure.h
#ifndef HELENDP_SOURCE_OBJECT_STRUCTURE_H_
#define HELENDP_SOURCE_OBJECT_STRUCTURE_H_
#include "people.h"
#include "action.h"
#include <list>
using namespace std;
class ObjectStructure{
public:
ObjectStructure();
~ObjectStructure();
void Add(People *people);
void Remove(People *people);
void FeedBack(Action *action);
private:
list<People *> people_list_;
};
#endif
//object_structure.cc
#include "object_structure.h"
ObjectStructure::ObjectStructure(){
}
ObjectStructure::~ObjectStructure(){
}
void ObjectStructure::Add(People *people){
people_list_.push_back(people);
}
void ObjectStructure::Remove(People * people){
people_list_.remove(people);
}
void ObjectStructure::FeedBack(Action *action){
list<People *>::iterator iterator;
for(iterator = people_list_.begin();iterator != people_list_.end();iterator++){
(*iterator)->Join(action);
}
}
Action:
//action.h
#ifndef HELENDP_SOURCE_ACTION_H_
#define HELENDP_SOURCE_ACTION_H_
class MalePeople;
class FemalePeople;
class Action{
public:
Action();
virtual ~Action();
virtual void GetMaleFeedBack(MalePeople *male_people) = 0;
virtual void GetFemaleFeedBack(FemalePeople *female_people) = 0;
};
#endif
//action.cc
#include "action.h"
Action::Action(){
}
Action::~Action(){
}
BikeAction:
//bike_action.h
#ifndef HELENDP_SOURCE_BIKE_ACTION_h_
#define HELENDP_SOURCE_BIKE_ACTION_h_
#include "action.h"
class BikeAction : public Action{
public:
BikeAction();
~BikeAction();
void GetMaleFeedBack(MalePeople *male_people);
void GetFemaleFeedBack(FemalePeople *female_people);
};
#endif
//bike_action.cc
#include "bike_action.h"
#include <iostream>
using namespace std;
BikeAction::BikeAction(){
}
BikeAction::~BikeAction(){
}
void BikeAction::GetMaleFeedBack(MalePeople * male_people){
cout << "GetMaleFeedBack(bike):一个人骑车,好无聊!" << endl;
}
void BikeAction::GetFemaleFeedBack(FemalePeople * female_people){
cout << "GetFemaleFeedBack(bike):风景很好,心情很好!" << endl;
}
RunAction:
//runner_action.h
#ifndef HELENDP_SOURCE_RUN_ACTION_h_
#define HELENDP_SOURCE_RUN_ACTION_h_
#include "action.h"
class RunAction : public Action{
public:
RunAction();
~RunAction();
void GetMaleFeedBack(MalePeople *male_people);
void GetFemaleFeedBack(FemalePeople *female_people);
};
#endif
//runner_action.cc
#include "run_action.h"
#include <iostream>
using namespace std;
RunAction::RunAction(){
}
RunAction::~RunAction(){
}
void RunAction::GetMaleFeedBack(MalePeople * male_people){
cout << "GetMaleFeedBack(run):大汗淋淋,够痛快!" << endl;
}
void RunAction::GetFemaleFeedBack(FemalePeople * female_people){
cout << "GetFemaleFeedBack(run):又累又无聊!" << endl;
}
SwimAction:
//swim_action.h
#ifndef HELENDP_SOURCE_SWIM_ACTION_h_
#define HELENDP_SOURCE_SWIM_ACTION_h_
#include "action.h"
class SwimAction : public Action{
public:
SwimAction();
~SwimAction();
void GetMaleFeedBack(MalePeople *male_people);
void GetFemaleFeedBack(FemalePeople *female_people);
};
#endif
//swim_action.cc
#include "swim_action.h"
#include <iostream>
using namespace std;
SwimAction::SwimAction(){
}
SwimAction::~SwimAction(){
}
void SwimAction::GetMaleFeedBack(MalePeople * male_people){
cout << "GetMaleFeedBack(swim):可以看美女,很好!" << endl;
}
void SwimAction::GetFemaleFeedBack(FemalePeople * female_people){
cout << "GetFemaleFeedBack(swim):可以秀身材,很不错!" << endl;
}
代码和UML图(EA)工程文件,最后会整理打包上传.
UML类图
结构
- Visitor(People):访问者抽象类.
- ConcreteVisitor(FemalePeople,MalePeople):访问者具体类.
- Element(Action):元素抽象类.
- ConcreteElement(BikeAction,RunAction,SwimAction):具体元素类.
- ObjectStructure(ObjectStructure):对象结构.
优点
- 访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易.
- 访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中.
- 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点.
- 积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点.
缺点
- 增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作.
- 破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的.