【Java设计模式】4访问者模式

定义

访问者模式(Visitor)是一种操作一组对象的操作,它的目的是不改变对象的定义,但允许新增不同的访问者,来定义新的操作。

UML图

【Java设计模式】4访问者模式_第1张图片

详细介绍

访问者模式(Visitor Pattern)是一种行为型设计模式,用于在不改变被访问元素的类的前提下,为这些元素定义新的操作。它将算法与元素的结构分离,使得可以在不修改元素类的情况下向元素对象添加新的操作。访问者模式通过双重分派来实现这一目标,即首先选择合适的访问者,然后再选择合适的元素。

访问者模式通常包括以下几个关键角色:

  1. 访问者(Visitor):定义了一组访问操作,每个操作对应一个具体元素类的操作。访问者可以通过多态来实现,为每个具体元素类提供不同的访问操作。

  2. 具体访问者(Concrete Visitor):实现了访问者接口中的具体操作,为元素提供了具体的行为。

  3. 元素(Element):定义了一个accept方法,该方法接受一个访问者作为参数,并将自身作为参数传递给访问者。这样,访问者就可以访问元素的内部状态。

  4. 具体元素(Concrete Element):实现了元素接口,提供了accept方法的具体实现。它包含了被访问的具体元素对象。

  5. 对象结构(Object Structure):维护了一个元素的集合,可以是一个列表、数组或其他数据结构。它提供了一个接受访问者的方法,用于遍历元素集合并调用各个元素的accept方法。

访问者模式的主要优点是能够将数据结构与数据操作分离,使得可以在不改变数据结构的前提下增加新的操作。这样的设计符合开闭原则。但访问者模式也有一些缺点,其中之一是增加了新元素类时需要修改所有的访问者类,因为每个访问者都需要实现新元素的访问方法。

以下是一个简单的Java示例,演示了访问者模式的应用:

// 访问者接口
interface Visitor {
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}

// 具体访问者A
class ConcreteVisitorA implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("Visitor A visits ConcreteElementA");
    }

    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("Visitor A visits ConcreteElementB");
    }
}

// 具体访问者B
class ConcreteVisitorB implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        System.out.println("Visitor B visits ConcreteElementA");
    }

    @Override
    public void visit(ConcreteElementB element) {
        System.out.println("Visitor B visits ConcreteElementB");
    }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

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

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

// 对象结构
class ObjectStructure {
    private Element[] elements;

    public ObjectStructure() {
        elements = new Element[]{new ConcreteElementA(), new ConcreteElementB()};
    }

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

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        
        Visitor visitorA = new ConcreteVisitorA();
        objectStructure.acceptVisitor(visitorA);

        Visitor visitorB = new ConcreteVisitorB();
        objectStructure.acceptVisitor(visitorB);
    }
}

在上面的示例中,Visitor 定义了两个访问方法,分别对应两种具体元素。ConcreteVisitorAConcreteVisitorB 是具体访问者,实现了对这两种元素的不同访问操作。Element 定义了一个accept方法,用于接受访问者的访问。ConcreteElementAConcreteElementB 是具体元素。ObjectStructure 维护了一个元素集合,并提供了一个接受访问者的方法,用于遍历元素并调用访问者的访问方法。客户端代码演示了如何创建访问者对象并将其应用于元素。

你可能感兴趣的:(java,设计模式,访问者模式)