欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Visitor模式

程序员文章站 2023-12-22 23:40:34
...

在开发时有时会遇到需求变动,这样就要经常去修改已有的设计.比较常见的是在实现好的类中添加新方法客户新需求.这时可以使用Visitor模式.

Visitor模式则提供了一种解决方案:将更新封装到一个类中,并由待更改类提供一个接收接口,来实现目的.

这里对对象(concreteElement)添加了一个统一的接口:Accept函数,来接收一个访问者对象.通过参数Visitor把对对象的操作移到类外,通过调用Visitor的接口函数visitConcreElement针对当前对象进行操作.

Visitor模式

函数Accept()是个双分派操作.调用哪一个Accept由Element类型和Visitor类型决定.

//Visitor.h

ifndef _VISITOR_H_
#define _VISITOR_H_
class ConcreteElementA;
class ConcreteEnementB;
class Element;
class Visitor
{
public:
    virtual ~Visitor();
    virtual void VisitConcreteElementA(Element* elm) = 0;
    virtual void VisitConcreteElementB(Element* eml) = 0;
protected:
    Visitor();
};
class ConcreteVisitorA :public Visitor
{
public:
    ConcreteVisitorA();
    virtual ~ConcreteVisitorA();
    virtual void VisitConcreteElementA(Element* elm) ;
    virtual void VisitConcreteElementB(Element* eml) ;
};
class ConcreteVisitorB :public Visitor
{
public:
    ConcreteVisitorB();
    virtual ~ConcreteVisitorB();
    virtual void VisitConcreteElementA(Element* elm);
    virtual void VisitConcreteElementB(Element* eml);
};
#endif

//Visitor.cpp

#include "Visitor.h"
#include "Element.h"
#include <iostream>

Visitor::Visitor()
{}
Visitor::~Visitor()
{}

ConcreteVisitorA::ConcreteVisitorA()
{}
ConcreteVisitorA::~ConcreteVisitorA()
{}
void ConcreteVisitorA::VisitConcreteElementA(Element* elm)
{
    std::cout << "i will visit ConcreteElementA." << std::endl;
}
void ConcreteVisitorA::VisitConcreteElementB(Element* elm)
{
    std::cout << "i will visit ConcreteElementB." << std::endl;
}

ConcreteVisitorB::ConcreteVisitorB()
{}
ConcreteVisitorB::~ConcreteVisitorB()
{}
void ConcreteVisitorB::VisitConcreteElementA(Element* elm)
{
    std::cout << "i will visit ConcreteElementA." << std::endl;
}
void ConcreteVisitorB::VisitConcreteElementB(Element* elm)
{
    std::cout << "i will visit ConcreteElementB." << std::endl;
}

//Element.h

#ifndef _ELEMENT_H_
#define _ELEMENT_H_
class Visitor;
class Element
{
public:
    virtual ~Element();
    virtual void Accept(Visitor* vis) = 0;
protected:
    Element();
};
class ConcreteElementA :public Element
{
public:
    ConcreteElementA();
    ~ConcreteElementA();
    void Accept(Visitor* vis);
};
class ConcreteElementB :public Element
{
public:
    ConcreteElementB();
    ~ConcreteElementB();
    void Accept(Visitor* vis);
};
#endif

//Element.cpp

#include "Element.h"
#include "Visitor.h"
#include <iostream>

Element::Element()
{}
Element::~Element()
{}
void Element::Accept(Visitor* vis)
{}

ConcreteElementA::ConcreteElementA()
{}
ConcreteElementA::~ConcreteElementA()
{}
void ConcreteElementA::Accept(Visitor* vis)
{
    vis->VisitConcreteElementA(this);
    std::cout << "visiting ConcreteElementA." << std::endl;
}

ConcreteElementB::ConcreteElementB()
{}
ConcreteElementB::~ConcreteElementB()
{}
void ConcreteElementB::Accept(Visitor* vis)
{
    vis->VisitConcreteElementB(this);
    std::cout << "visiting ConcreteElementB." << std::endl;
}

//main.cpp

#include "Element.h"
#include "Visitor.h"
#include <iostream>

int main()
{
    Visitor* vis = new ConcreteVisitorA();
    Element* elm = new ConcreteElementA();
    elm->Accept(vis);
    return 0;
}

上一篇:

下一篇: