设计模式--第14篇(访问者模式)

一,访问者模式

访问者模式:

  1. 在被访问的类里面加一个对外提供接待访问者的接口;
  2. 封装一些作用于某种数据结构的各元素的操作,可以在不改变数据结构的前提下,定义作用于这些元素的新的操作;
  3. 将数据结构和数据操作分离,解决数据结构与数据操作的耦合性问题;

二,原理类图

在这里插入图片描述
意图: 封装一些作用于某种数据结构的各元素的操作,可以在不改变数据结构的前提下,定义作用于这些元素的新的操作
适用性:
当需要对一个对象结构中的对象进行很多不同操作(这些操作可能没有关联),同时需要避免这些操作“污染”这些对象的类,可以考虑访问者模式;

三,实例

双分派:
首先,将Visitor作为参数传给Element(第一次分派);
然后在将Element自己传给Visitor的方法中去执行(第二次分派);

Visitor接口: 抽象访问者,为ConcreteElement中的每个类声明一个visit操作

package com.neei.visitor;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/14  20:24
 * @Description: 游学网
 * @throws:
 */
public interface Action {
    /**
     * 男性评分
     *
     * @param man
     */
    void getManResult(Man man);

    /**
     * 女性评分
     *
     * @param woMan
     */
    void getWoManResult(WoMan woMan);
}

ConcreteVisitor: 具体的访问者,实现每个Visitor声明的操作,是每个操作的实现部分。

package com.neei.visitor;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/14  20:30
 * @Description: 游学网
 * @throws:
 */
public class Success implements Action {
    @Override
    public void getManResult(Man man) {
        System.out.println(man.getName() + ":机智过人");
    }

    @Override
    public void getWoManResult(WoMan woMan) {
        System.out.println(woMan.getName() + ":机智过人");
    }
}
public class Fail implements Action {
    @Override
    public void getManResult(Man man) {
        System.out.println(man.getName() + ":技不如人");
    }

    @Override
    public void getWoManResult(WoMan woMan) {
        System.out.println(woMan.getName() + ":技不如人");
    }
}

public class Equal implements Action {
    @Override
    public void getManResult(Man man) {
        System.out.println(man.getName() + ":不相上下");
    }

    @Override
    public void getWoManResult(WoMan woMan) {
        System.out.println(woMan.getName() + ":不相上下");
    }
}

ObjectStructure: 能够枚举元素,提供一个高层的接口,允许访问者访问元素;

package com.neei.visitor;

import java.lang.invoke.VolatileCallSite;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/14  20:40
 * @Description: 游学网
 * @throws:
 */
public class ObjectStructure {
    private List<Person> list = new LinkedList<>();

    public void add(Person person) {
        list.add(person);
    }

    public void deleted(Person person) {
        list.remove(person);
    }

    public void display(Action action) {
        for (Person person : list) {
            person.accept(action);
        }
    }

}

Element接口: 定义accept方法,接收一个访问者对象;

package com.neei.visitor;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/14  20:24
 * @Description: 游学网
 * @throws:
 */
public abstract class Person {
    /**
     * 提供访问方法
     *
     * @param action
     */
    abstract void accept(Action action);

    private String name;

    public String getName() {
        return name;
    }

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

    public Person(String name) {
        this.name = name;
    }
}

ConcreteElement: 具体元素,实现accept方法;

package com.neei.visitor;

/**
 * @param
 * @Author: AaNeei
 * @Date: 2019/10/14  20:29
 * @Description: 游学网
 * @throws:
 */
public class WoMan extends Person {
    public WoMan(String name) {
        super(name);
    }
    /**
     * 双分派
     * @param action
     */
    @Override
    void accept(Action action) {
        action.getWoManResult(this);
    }
}


public class Man extends Person {
    public Man(String name) {
        super(name);
    }
    /**
     * 双分派
     * @param action
     */
    @Override
    void accept(Action action) {
        action.getManResult(this);
    }
}

四,源码分析

JDK源码中使用的访问者模式,如java.nio.file.FileVisitor

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值