设计模式(23)-行为型模式-VISITOR模式

3.11.1功能

在面向对象系统的开发和设计过程,经常会遇到一种情况就是需求变更(ChangeRequest),经常我们做好的一个设计、实现了一个系统原型,咱们的客户又会有了新的需求。我们又因此不得不去修改已有的设计,最常见就是解决方案就是给已经设计、实现好的类添加新的方法去实现客户新的需求,这样就陷入了设计变更的梦魇:不停地打补丁,其带来的后果就是设计根本就不可能封闭、编译永远都是整个系统代码。

Visitor模式则提供了一种解决方案:将更新(变更)封装到一个类中(Vistor),并由待更改类提供一个接收接口,则可达到效果。

3.11.2 结构图


•  Vi s i t o r(访问者,如N o d e Vi s i t o r)
— 为该对象结构中C o n c r e t e E l e m e n t的每一个类声明一个Vi s i t 操作。该操作的名字和特征标识了发送Vi s i t 请求给哪个访问者。

•  C o n c r e t e Vi s i t o r(具体访问者,如 Ty p e C h e c k i ng Vi s i t o r)
— 实现每个由Vi s i t o r 声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。

•  E l e m e n t(元素,如 N o d e)
— 定义一个Ac c e p t操作,它以一个访问者为参数。


•  C o n c r e t e E l e m e n t(具体元素,如As s i g n m e n t N o d e,Va r i a b l e R e f N o d e)
— 实现Ac c e p t操作,该操作以一个访问者为参数。

•  O b j e c t S t r u c t u r e
— 能枚举它的元素。
— 可以提供一个高层的接口以允许该访问者访问它的元素。
— 可以是一个复合(参见C o m p o s i t e(4. 3) )或是一个集合,如一个列表或一个无序集合。

3.11.3 协作


• 一个使用Vi s i t o r 模式的客户必须创建一个C o n c r e t e Vi s i t o r对象,然后遍历该对象结构,并用该访问者访问每一个元素。

• 当一个元素被访问时,它调用对应于它的类的Vi s i t o r操作。如果必要,该元素将自身作为这个操作的一个参数以便该访问者访问它的状态。

3.11.4 C++代码示例

//Visitor.h

#ifndef _VISITOR_H_

#define _VISITOR_H_

class ConcreteElementA;

class ConcreteElementB;

class Element;

class Visitor

{

public:

       virtual ~Visitor();

       virtual void

              VisitConcreteElementA(Element* elm) = 0;

       virtual void

              VisitConcreteElementB(Element* elm) = 0;

protected:

       Visitor();

private:

};

class ConcreteVisitorA :public Visitor

{

public:

       ConcreteVisitorA();

       virtual ~ConcreteVisitorA();

       virtual void

              VisitConcreteElementA(Element* elm);

       virtual void

              VisitConcreteElementB(Element* elm);

protected:

private:

};

class ConcreteVisitorB :public Visitor

{

public:

       ConcreteVisitorB();

       virtual ~ConcreteVisitorB();

       virtual void

              VisitConcreteElementA(Element* elm);

       virtual void

              VisitConcreteElementB(Element* elm);

protected:

private:

};

#endif //~_VISITOR_H_

 

//Visitor.cpp

#include "Visitor.h"

#include "Element.h"

#include <iostream>

using namespace std;

Visitor::Visitor()

{

}

Visitor::~Visitor()

{

}

ConcreteVisitorA::ConcreteVisitorA()

{

}

ConcreteVisitorA::~ConcreteVisitorA()

{

}

void ConcreteVisitorA::VisitConcreteElementA(Element* elm)

{

       cout << "i willvisit ConcreteElementA..."<<endl;

}

void

ConcreteVisitorA::VisitConcreteElementB(Element*elm)

{

       cout << "i will  visitConcreteElementB..."<<endl;

}

ConcreteVisitorB::ConcreteVisitorB()

{

}

ConcreteVisitorB::~ConcreteVisitorB()

{

}

void ConcreteVisitorB::VisitConcreteElementA(Element* elm)

{

       cout << "i will  visitConcreteElementA..."<<endl;

}

void ConcreteVisitorB::VisitConcreteElementB(Element* elm)

{

       cout << "i will visit ConcreteElementB..."<<endl;

}

 

//Element.h

#ifndef _ELEMENT_H_

#define _ELEMENT_H_

class Visitor;

class Element

{

public:

       virtual ~Element();

       virtual void Accept(Visitor*vis) = 0;

protected:

       Element();

private:

};

class ConcreteElementA :public Element

{

public:

       ConcreteElementA();

       ~ConcreteElementA();

       void Accept(Visitor* vis);

protected:

private:

};

class ConcreteElementB :public Element

{

public:

       ConcreteElementB();

       ~ConcreteElementB();

       void Accept(Visitor* vis);

protected:

private:

};

#endif //~_ELEMENT_H_

//Element.cpp

#include"Element.h"

#include"Visitor.h"

#include<iostream>

using namespace std;

Element::Element()

{

}

 

Element::~Element()

{

}

 

void Element::Accept(Visitor*vis)

{

}

 

ConcreteElementA::ConcreteElementA()

{

}

 

ConcreteElementA::~ConcreteElementA()

{

}

 

void ConcreteElementA::Accept(Visitor* vis)

{

       vis->VisitConcreteElementA(this);

       cout << "visiting ConcreteElementA..."<<endl;

}

 

ConcreteElementB::ConcreteElementB()

{

}

 

ConcreteElementB::~ConcreteElementB()

{

}

 

void ConcreteElementB::Accept(Visitor* vis)

{

       cout << "visiting ConcreteElementB..."<<endl;

              vis->VisitConcreteElementB(this);

}

 

//main.cpp
#include"Element.h"
#include"Visitor.h"
#include<iostream>
using namespace std;

int main(int argc, char*argv[])

{

       Visitor* vis = new ConcreteVisitorA();

       Element*elm = new

              ConcreteElementA();

       elm->Accept(vis);

       return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值