访问者模式 Vistor
定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
类型:行为类模式
类图:
结构对象中的元素类在accept的时候将自身作为参数 vistor类,Vistor类通过此参数获得一些相关信息。
代码中:Person为Element抽象类
Man WoMan为具体元素类
ObjectStruct为结构对象类
Action为Vistor抽象类
AngryAction,SadAction为Vistor具体类
// Vistor.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <string> #include <list> using namespace std; class Person; // 只是声明这是一个 class,有什么成员还不知道,只能定义指针类型 ICommand * // 成员是没法访问的 class Action{ public: virtual void GetManAction(Person * ) = 0; virtual void GetWomenAction(Person *) = 0; }; class Person{ //Action的具体类与Person的具体类中相互包含实用成员函数,将两者的抽象类放于所有具体类之前,可以编译通过 //更一般的情况,声明放前面,不要实现,因为之前只声明了另一个类,只能定义其指针,不能获取其成员函数 public: Person(string name):m_name(name){} virtual void accept(Action * action) = 0; string getname(){ return m_name; } private: string m_name; }; class AngryAction:public Action{ public: void GetManAction(Person * person){ cout<<"男人("<<person->getname()<<"):大叫"<<endl; } void GetWomenAction(Person * person){ cout<<"女人("<<person->getname()<<"):尖叫"<<endl; } }; class SadAction:public Action{ public: void GetManAction(Person * person){ cout<<"男人("<<person->getname()<<"):喝酒"<<endl; } void GetWomenAction(Person * person){ cout<<"女人("<<person->getname()<<"):哭泣"<<endl; } }; class Man:public Person{ public: Man(string name):Person(name){} void accept(Action * action){ action->GetManAction(this); } }; class WoMan:public Person{ public: WoMan(string name):Person(name){} void accept(Action * action){ action->GetWomenAction(this); } }; class ObjectStruct{ public: void Attach(Person *p){ m_list.push_back(p); } void Detach(Person *p){ m_list.remove(p); } void Accept(Action * paction){ list<Person *>::iterator it ; for(it = m_list.begin();it != m_list.end();it++){ (*it)->accept(paction); } } private: list<Person *> m_list; }; int main(int argc,char * argv[]){ ObjectStruct * pobstruct = new ObjectStruct; pobstruct->Attach(new Man("老王")); pobstruct->Attach(new WoMan("小红")); Action * paction1 = new AngryAction; pobstruct->Accept(paction1); Action * paction2 = new SadAction; pobstruct->Accept(paction2); }