访问者模式是一种行为型设计模式,它可以在不修改现有代码结构的情况下,为复杂的对象结构添加新的操作。该模式将数据结构和数据操作进行分离,使得数据结构可以独立于操作进行变化,同时也可以在不改变操作的前提下增加新的操作。
在访问者模式中,主要有以下几个角色:
① 访问者(Visitor):定义了对每个元素对象访问时所要执行的操作,可以通过多态实现针对不同元素的不同操作。
② 具体访问者(ConcreteVisitor):实现了访问者定义的接口,完成对元素对象的具体操作。
③ 元素(Element):定义了一个 `accept` 方法,用于接受访问者的访问。
④ 具体元素(ConcreteElement):实现了元素定义的接口,通常会在 `accept` 方法中调用访问者的方法。
⑤ 对象结构(ObjectStructure):包含一个元素的集合,通常提供一个方法让访问者遍历所有元素。
访问者模式适用于对象结构比较稳定,但经常需要在此对象结构上定义新的操作的情况,或者有复杂的对象结构需要一些独立的操作的情况。

1、场景设计

实现场景:对象结构中定义A、B两个元素,访问者对它们进行访问。

2、C++实现

`Visitor` 是抽象访问者类,`ConcreteVisitor` 是具体访问者类,`Element` 是抽象元素类,`ConcreteElementA` 和 `ConcreteElementB` 是具体元素类。`ObjectStructure` 是对象结构类,包含了一个元素的集合,可以接受访问者的访问。在 `main` 函数中,我们创建了一个具体的访问者和一个对象结构,然后向对象结构中添加了两个具体元素,最后让访问者访问对象结构。 

#include <iostream>
#include <vector>

// 前置声明,防止循环引用
class ConcreteElementB;

// 抽象访问者类
class Visitor {
    public:
        virtual void visit(ConcreteElementB* element) = 0;
};

// 具体访问者类
class ConcreteVisitor : public Visitor {
    public:
        void visit(ConcreteElementB* element) override {
            std::cout << "ConcreteVisitor is visiting ConcreteElementB" << std::endl;
        }
};

// 抽象元素类
class Element {
    public:
        virtual void accept(Visitor* visitor) = 0;
};

// 具体元素类A
class ConcreteElementA : public Element {
    public:
        void accept(Visitor* visitor) override {
            std::cout << "ConcreteElementA is accepting visitor" << std::endl;
        }
};

// 具体元素类B
class ConcreteElementB : public Element {
    public:
        void accept(Visitor* visitor) override {
            visitor->visit(this);
        }
};

// 对象结构类
class ObjectStructure {
    private:
        std::vector<Element*> elements;

    public:
        void addElement(Element* element) {
            elements.push_back(element);
        }

        void accept(Visitor* visitor) {
            for (Element* element : elements) {
                element->accept(visitor);
            }
        }
};

int main() {
    ConcreteVisitor visitor;
    ObjectStructure objectStructure;

    ConcreteElementA elementA;
    ConcreteElementB elementB;

    objectStructure.addElement(&elementA);
    objectStructure.addElement(&elementB);

    objectStructure.accept(&visitor);

    return 0;
}

3、Java实现

`Visitor` 是抽象访问者类,`ConcreteVisitor` 是具体访问者类,`Element` 是抽象元素类,`ConcreteElementA` 和 `ConcreteElementB` 是具体元素类。`ObjectStructure` 是对象结构类,包含了一个元素的集合,可以接受访问者的访问。在 `main` 方法中,我们创建了一个具体的访问者和一个对象结构,向对象结构中添加了两个具体元素,并让访问者访问对象结构。 

package behavioralpattern.visitor;

import java.util.ArrayList;
import java.util.List;

// 抽象访问者类
interface Visitor {
    void visit(ConcreteElementB element);
}

// 具体访问者类
class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("ConcreteVisitor is visiting ConcreteElementB");
    }
}

// 抽象元素类
interface Element {
    void accept(Visitor visitor);
}

// 具体元素类A
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        System.out.println("ConcreteElementA is accepting visitor");
    }
}

// 具体元素类B
class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 对象结构类
class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

public class VisitorDemo {
    public static void main(String[] args) {
        ConcreteVisitor visitor = new ConcreteVisitor();
        ObjectStructure objectStructure = new ObjectStructure();

        ConcreteElementA elementA = new ConcreteElementA();
        ConcreteElementB elementB = new ConcreteElementB();

        objectStructure.addElement(elementA);
        objectStructure.addElement(elementB);

        objectStructure.accept(visitor);
    }
}
04-17 08:59