【设计模式之访问者模式 -- C++】

访问者模式 -- 操作对象,分离算法

访问者模式(Visitor Pattern)是一种将算法与对象结构分离的设计模式。这种模式主要用于操作一个由许多对象构成的复杂对象结构,它能够在不修改这些对象的类的前提下定义作用于这些对象的新操作。

组成
  1. 访问者(Visitor)接口:定义了对每一个元素(Element)类访问操作的接口。通常会有一个访问方法对应每种类型的元素。
  2. 具体访问者(Concrete Visitor)类:实现访问者接口,定义了对每一个元素的具体访问行为。
  3. 元素(Element)接口:定义了一个接受访问者的方法(accept),该方法通常有一个访问者作为参数。
  4. 具体元素(Concrete Element)类:实现元素接口,定义了接受访问者的具体操作,通常是让访问者访问自己的元素。
  5. 对象结构(Object Structure):一个元素的集合,它提供了一个接口,允许访问者遍历自己的元素。
工作原理
  1. 访问者模式通过将数据结构与数据操作分离,使得在不修改已有程序结构的情况下,可以向已有的对象结构中添加新的操作。
  2. 当需要对一个复杂的对象结构(如组合树)进行操作时,可以使用访问者模式来避免对每个节点类都添加操作。相反,可以创建访问者类来专门处理这些操作。
  3. 元素类通过接受一个访问者对象,将自身作为参数传递给访问者的访问方法,从而实现对元素的操作。
优点
  1. 易于添加新的操作,增强了系统的灵活性。
  2. 将相关的操作集中到一个访问者对象中,而不是分散在多个元素类中,有助于集中管理和维护。
缺点
  1. 增加新的元素类变得困难,因为每增加一个新的元素类,都需要在每个访问者类中增加相应的访问操作。
  2. 可能会破坏封装,因为访问者模式通常需要元素类暴露一些访问其内部状态的操作,这可能会违反其封装原则。
实现
  1. 访问者(Visitor)接口:定义了对每一个元素(Element)类访问操作的接口。通常会有一个访问方法对应每种类型的元素。
cpp 复制代码
class Visitor {
public:
    virtual void visitConcreteElementA(ConcreteElementA* elementA) = 0;
    virtual void visitConcreteElementB(ConcreteElementB* elementB) = 0;
    virtual ~Visitor() = default;
};
  1. 具体访问者(Concrete Visitor)类:实现访问者接口,定义了对每一个元素的具体访问行为。
cpp 复制代码
// 具体访问者1
class ConcreteVisitor1 : public Visitor {
public:
    void visitConcreteElementA(ConcreteElementA* elementA) override {
        std::cout << "ConcreteVisitor1 visiting ConcreteElementA" << std::endl;
        elementA->operationA();
    }
    void visitConcreteElementB(ConcreteElementB* elementB) override {
        std::cout << "ConcreteVisitor1 visiting ConcreteElementB" << std::endl;
        elementB->operationB();
    }
};

// 具体访问者2
class ConcreteVisitor2 : public Visitor {
public:
    void visitConcreteElementA(ConcreteElementA* elementA) override {
        std::cout << "ConcreteVisitor2 visiting ConcreteElementA" << std::endl;
        elementA->operationA();
    }
    void visitConcreteElementB(ConcreteElementB* elementB) override {
        std::cout << "ConcreteVisitor2 visiting ConcreteElementB" << std::endl;
        elementB->operationB();
    }
};
  1. 元素(Element)接口:定义了一个接受访问者的方法(accept),该方法通常有一个访问者作为参数。
cpp 复制代码
class Element {
public:
    virtual void accept(Visitor* visitor) = 0; // 接受访问者
    virtual ~Element() = default;
};
  1. 具体元素(Concrete Element)类:实现元素接口,定义了接受访问者的具体操作,通常是让访问者访问自己的元素。
cpp 复制代码
// 具体元素A
class ConcreteElementA : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visitConcreteElementA(this);
    }
    void operationA() {
        std::cout << "ConcreteElementA operationA" << std::endl;
    }
};

// 具体元素B
class ConcreteElementB : public Element {
public:
    void accept(Visitor* visitor) override {
        visitor->visitConcreteElementB(this);
    }
    void operationB() {
        std::cout << "ConcreteElementB operationB" << std::endl;
    }
};
  1. 对象结构(Object Structure):一个元素的集合,它提供了一个接口,允许访问者遍历自己的元素。
cpp 复制代码
int main() {
    std::vector<std::unique_ptr<Element>> elements;
    elements.push_back(std::make_unique<ConcreteElementA>());
    elements.push_back(std::make_unique<ConcreteElementB>());

    ConcreteVisitor1 visitor1;
    ConcreteVisitor2 visitor2;

    for (auto& element : elements) {
        element->accept(&visitor1);
        element->accept(&visitor2);
    }

    return 0;
}
  1. 结果
shell 复制代码
ConcreteVisitor1 visiting ConcreteElementA
ConcreteElementA operationA
ConcreteVisitor2 visiting ConcreteElementA
ConcreteElementA operationA
ConcreteVisitor1 visiting ConcreteElementB
ConcreteElementB operationB
ConcreteVisitor2 visiting ConcreteElementB
ConcreteElementB operationB
相关推荐
AA陈超11 小时前
ASC学习笔记0010:效果被应用时的委托
c++·笔记·学习
AA陈超11 小时前
ASC学习笔记0004:通知相关方能力规格已被修改
c++·笔记·学习·游戏·ue5·游戏引擎·虚幻
阿巴~阿巴~11 小时前
IPv4地址转换函数详解及C++容器安全删除操作指南
linux·服务器·c++·网络协议·算法·c++容器安全删除操作·ipv4地址转换函数
oioihoii11 小时前
C/C++混合项目中的头文件管理:.h与.hpp的分工与协作
java·c语言·c++
彷徨而立12 小时前
【C/C++】不能在派生类的构造函数初始化列表中直接初始化属于基类的成员变量
c语言·c++
小二·12 小时前
设计模式面试题(14道含答案)
设计模式
@宁兰12 小时前
算法实现总结 - C/C++
c语言·c++·算法
乌萨奇也要立志学C++13 小时前
【Linux】进程间通信(三)System V 共享内存完全指南:原理、系统调用与 C++ 封装实现
linux·c++
雪域迷影13 小时前
C++ 11 中的move赋值运算符
开发语言·c++·move
jf加菲猫13 小时前
第2章 Hello World
开发语言·c++·qt·ui