行为型模式——访问者模式(十)

该项目源码地址:https://github.com/ggb2312/JavaNotes/tree/master/design-pattern (设计模式相关代码与笔记)

1. 定义

封装作用于某数据结构(如List/Set/Map等)中的各元素的操作(可以在不改变各元素的类的前提下,定义作用于这些元素的操作)

2. 适用场景

  • 一个数据结构如(List/Set/Map等)包含很多类型对象
  • 数据结构与数据操作分离

3. 类图以及角色

类图

Visitor:接口或者抽象类,它定义了对每一个元素(Element)访问的行为,它的参数就是可以访问的元素,它的方法数理论上来讲与元素个数是一样的,因此,访问者模式要求元素的类族要稳定,如果经常添加、移除元素类,必然会导致频繁地修改Visitor接口,如果这样则不适合使用访问者模式。
ConcreteVisitor1、ConcreteVisitor2:具体的访问类,它需要给出对每一个元素类访问时所产生的具体行为。
Element:元素接口或者抽象类,它定义了一个接受访问者的方法(Accept),其意义是指每一个元素都要可以被访问者访问。
ConcreteElementA、ConcreteElementB:具体的元素类,它提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。
ObjectStructure:定义当中所说的对象结构,对象结构是一个抽象表述,它内部管理了元素集合,并且可以迭代这些元素供访问者访问。

3. 相关设计模式

访问者模式和迭代器模式

  • 相同点:都是在某种数据结构上面处理
  • 不同点:访问者模式用于对保存在数据结构的元素进行某种特定的处理,迭代器模式重要用于逐个遍历在数据结构中的元素。

4. 模式实例

背景:不同的访问者(普通用户、老板)查看不同的课程(免费课程、收费课程),可以看到不同的结果。

(1)Visitor 访问者接口

/**
 * Create by eval on 2019/2/11
 */
public interface IVisitor {
    void visit(FreeCourse freeCourse);

    void visit(CodingCourse codingCourse);
}

(2)ConcreteVisitor 访问者实现类

/**
 * Create by eval on 2019/2/11
 */
public class Visitor implements IVisitor {
    /**
     * 访问免费课程,打印所有免费课程名称
     *
     * @param freeCourse
     */
    @Override
    public void visit(FreeCourse freeCourse) {
        System.out.println("免费课程:" + freeCourse.getName());
    }

    /**
     * 访问实战课程,打印所有实战课程名称以及价格
     *
     * @param codingCourse
     */
    @Override
    public void visit(CodingCourse codingCourse) {
        System.out.println("实战课程:" + codingCourse.getName() + " 价格:" + codingCourse.getPrice()+ "元");
    }
}

(3)Element 课程接口

/**
 * Create by eval on 2019/2/11
 */
public abstract class Course {
    private String name;

    public String getName() {
        return name;
    }

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

    public abstract void accept(IVisitor visitor);
}

(4)ConcreteElement 课程实现类

/**
 * Create by eval on 2019/2/11
 */
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(IVisitor visitor) {
        visitor.visit(this);
    }
}
/**
 * Create by eval on 2019/2/11
 */
public class FreeCourse extends Course {
    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

(5)测试

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

/**
 * Create by eval on 2019/2/11
 */
public class Test {
    public static void main(String[] args) {
        List<Course> courseList = new ArrayList<>();

        FreeCourse freeCourse = new FreeCourse();
        freeCourse.setName("SpringMVC数据绑定");

        CodingCourse codingCourse = new CodingCourse();
        codingCourse.setName("Java设计模式");
        codingCourse.setPrice(299);

        courseList.add(freeCourse);
        courseList.add(codingCourse);

        for (Course course : courseList) {
            course.accept(new Visitor());
        }
    }
}

测试结果:

测试结果

5. 优缺点

优点:

  • 增加新的操作很容易,即增加一个新的访问者

缺点:

  • 增加新的数据结构困难
  • 具体元素变更比较麻烦

6. 扩展-JDK1.7源码以及框架中的访问者模式

java.nio.file.FileVisitor以及实现类SimpleFileVisitor

org.springframework.beans.factory.config.BeanDefinitionVisitor可以遍历Bean的各种属性,委托valueResolver来实现

参考

https://www.cnblogs.com/chenssy/p/3339756.html

猜你喜欢

转载自www.cnblogs.com/gj-blog/p/10929607.html
今日推荐