设计模式——访问者模式

2020-05-01  本文已影响0人  小波同学

什么是访问者模式

访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

可以对定义这么理解:有这么一个操作,它是作用于一些元素之上的,而这些元素属于某一个对象结构。同时这个操作是在不改变各元素类的前提下,在这个前提下定义新操作是访问者模式精髓中的精髓。

主要解决:稳定的数据结构和易变的操作耦合问题。就是把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。

本质:预留通路,回调实现。它的实现主要就是通过预先定义好调用的通路,在被访问的对象上定义accept方法,在访问者的对象上定义visit方法;然后在调用真正发生的时候,通过两次分发的技术,利用预先定义好的通路,回调到访问者具体的实现上。

访问者模式的结构

Visitor抽象访问者接口:它定义了对每一个元素(Element)访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素个数(Element的实现类个数)是一样的,从这点不难看出,访问者模式要求元素类的个数不能改变(不能改变的意思是说,如果元素类的个数经常改变,则说明不适合使用访问者模式)。

ConcreteVisitor具体访问者角色:它需要给出对每一个元素类访问时所产生的具体行为。

Element抽象节点(元素)角色:它定义了一个接受访问者(accept)的方法,其意义是指,每一个元素都要可以被访问者访问。

ConcreteElement具体节点(元素)角色:它提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。

ObjectStructure结构对象角色:这个便是定义当中所提到的对象结构,对象结构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特性的类,它会含有一组元素(Element),并且可以迭代这些元素,供访问者访问。

访问者模式的使用场景

通常在以下情况可以考虑使用访问者(Visitor)模式。

访问者模式的优缺点

访问者(Visitor)模式是一种对象行为型模式,其主要优点如下:

访问者(Visitor)模式的主要缺点如下:

访问者模式的实现

抽象访问者角色:为每一个具体节点都准备了一个访问操作。
public interface Visitor {

    void visit(FreeCourse freeCourse);

    void visit(CodingCourse codingCourse);
}
具体访问者
public class VisitorImpl implements Visitor {
    @Override
    public void visit(FreeCourse freeCourse) {
        //访问免费课程,打印所有的免费课程名称
        System.out.println("免费课程:"+freeCourse.getName());
    }

    @Override
    public void visit(CodingCourse codingCourse) {
        //访问收费课程,打印所有的收费课程名称及价格
        System.out.println("收费课程:"+codingCourse.getName()+",价格:"+codingCourse.getPrice());
    }
}
抽象节点类
public abstract class Course {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void accept(Visitor visitor);
}
具体节点类
public class CodingCourse extends Course {

    private int price;

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

public class FreeCourse extends Course {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
结构对象角色类
public class ObjectStructure {

    private List<Course> courseList = new ArrayList<>();

    public void accept(Visitor visitor){
        courseList.forEach(course -> course.accept(visitor));
    }

    public void add(Course course){
        courseList.add(course);
    }

    public void remove(Course course){
        courseList.remove(course);
    }
}
客户端代码
public class Test {

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

        FreeCourse freeCourse = new FreeCourse();
        freeCourse.setName("Spring课程");

        CodingCourse codingCourse = new CodingCourse();
        codingCourse.setName("SpringBoot课程");
        codingCourse.setPrice(399);

        objectStructure.add(freeCourse);
        objectStructure.add(codingCourse);

        objectStructure.accept(new VisitorImpl());
    }
}

访问者(Visitor)模式的扩展

访问者(Visitor)模式是使用频率较高的一种设计模式,它常常同以下两种设计模式联用。

参考:
http://c.biancheng.net/view/1397.html

https://www.cnblogs.com/xuwendong/p/9898021.html

上一篇下一篇

猜你喜欢

热点阅读