【设计模式之访问者模式 -- 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
相关推荐
渊渟岳3 分钟前
掌握设计模式--装饰模式
设计模式
szuzhan.gy21 分钟前
DS查找—二叉树平衡因子
数据结构·c++·算法
火云洞红孩儿1 小时前
基于AI IDE 打造快速化的游戏LUA脚本的生成系统
c++·人工智能·inscode·游戏引擎·lua·游戏开发·脚本系统
FeboReigns2 小时前
C++简明教程(4)(Hello World)
c语言·c++
FeboReigns2 小时前
C++简明教程(10)(初识类)
c语言·开发语言·c++
zh路西法2 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(二):从FSM开始的2D游戏角色操控底层源码编写
c++·游戏·unity·设计模式·状态模式
.Vcoistnt3 小时前
Codeforces Round 994 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划
小k_不小3 小时前
C++面试八股文:指针与引用的区别
c++·面试
夏旭泽3 小时前
设计模式-备忘录模式
设计模式·备忘录模式
沐泽Mu3 小时前
嵌入式学习-QT-Day07
c++·qt·学习·命令模式