設計模式--第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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章