Skip to content

访问者模式

回到目录

简介

参考链接

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

UML类图

代码示例

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Visitor;
// 被访问元素
class Element
{
protected: 
    std::string m_strName;
public:
    Element(std::string str) { m_strName = str; }
    virtual void Accept(Visitor *visitor) = 0;

    std::string getName() { return m_strName; }
};

class ConcreteElementA : public Element
{
public:
    ConcreteElementA(std::string str) : Element(str) {}
    void Accept(Visitor *visitor);
};

class ConcreteElementB : public Element
{
public: 
    ConcreteElementB(std::string str) : Element(str) {}
    void Accept(Visitor *visitor);
};

// 访问者
class Visitor
{
public:
    virtual void VisitConcreteElementA(ConcreteElementA *p) = 0;
    virtual void VisitConcreteElementB(ConcreteElementB *p) = 0;
};

class ConcreteVisitorA : public Visitor
{
public:
    void VisitConcreteElementA(ConcreteElementA *p)
    {
        std::cout << "ConcreteVisitorA 访问了" << p->getName() << std::endl;
    }
    void VisitConcreteElementB(ConcreteElementB *p)
    {
        std::cout << "ConcreteVisitorA 访问了" << p->getName() << std::endl;
    }
};

class ConcreteVisitorB : public Visitor
{
public:
    void VisitConcreteElementA(ConcreteElementA *p)
    {
        std::cout << "ConcreteVisitorB 访问了" << p->getName() << std::endl;
    }
    void VisitConcreteElementB(ConcreteElementB *p)
    {
        std::cout << "ConcreteVisitorB 访问了" << p->getName() << std::endl;
    }
};

void ConcreteElementA::Accept(Visitor *visitor)
{
    visitor->VisitConcreteElementA(this);
}
void ConcreteElementB::Accept(Visitor *visitor)
{
    visitor->VisitConcreteElementB(this);
}

// 聚集类
class ObjectStructure
{
private:
    std::vector<Element *> m_vec;
public:
    ~ObjectStructure() {
        for (auto it = m_vec.begin(); it != m_vec.end(); it++) {
            delete *it;
        }
        m_vec.clear();
    }

    void add(Element *p) { m_vec.push_back(p); }
    void accept(Visitor *visitor) {
        for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++) {
            (*it)->Accept(visitor);
        }
    }
};

int main()
{
    // 访问者模式
    ObjectStructure *p = new ObjectStructure();
    p->add(new ConcreteElementA("AElement"));
    p->add(new ConcreteElementB("B"));

    ConcreteVisitorA *pVisitorA = new ConcreteVisitorA();
    ConcreteVisitorB *pVisitorB = new ConcreteVisitorB();

    p->accept(pVisitorA);
    p->accept(pVisitorB);

    delete pVisitorA;
    delete pVisitorB;
    delete p;

    return 0;
}