今天我们来学习23种设计模式中的访问者模式。访问者模式主要用于解决稳定的数据结构和易变的操作耦合的问题。 概念: 访问者模式是将作用于某种数据结构中的各元素的操作分离出
          今天我们来学习23种设计模式中的访问者模式。访问者模式主要用于解决稳定的数据结构和易变的操作耦合的问题。
概念:
访问者模式是将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为型设计模式中最复杂的一种模式。
特点:
优点:
- 符合单一职责原则。
- 优秀的扩展性。
- 灵活性。
缺点:
- 具体元素对访问者公布细节,违反了迪米特原则。
- 具体元素变更比较困难。
- 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
代码:
抽象行为类
package cn.ppdxzz.visitor;
/**
 * description:抽象行为类
 */
public abstract class AbstractAction {
    /**
     * 获取男性的测评
     * @param man 男人对象
     */
    public abstract void getManResult(Man man);
    /**
     * 获取女性的测评
     * @param woman 女人对象
     */
    public abstract void getWomanResult(Woman woman);
}
人的抽象类
package cn.ppdxzz.visitor;
/**
 * description:人的抽象类
 */
public abstract class AbstractPerson {
    /**
     * 提供一个方法,让访问者可以访问
     * @param action 行为
     */
    public abstract void accept(AbstractAction action);
}
男人
package cn.ppdxzz.visitor;
/**
 * description:男人
 */
public class Man extends AbstractPerson {
    @Override
    public void accept(AbstractAction action) {
        action.getManResult(this);
    }
}
女人
package cn.ppdxzz.visitor;
/**
 * description:女人
 */
public class Woman extends AbstractPerson {
    @Override
    public void accept(AbstractAction action) {
        action.getWomanResult(this);
    }
}
成功评价类
package cn.ppdxzz.visitor;
/**
 * description:成功评价类
 */
public class Success extends AbstractAction {
    @Override
    public void getManResult(Man man) {
        System.out.println("男人对该歌手的评价是成功的!");
    }
    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("女人对该歌手的评价是成功的!");
    }
}
失败评价类
package cn.ppdxzz.visitor;
/**
 * description:失败评价类
 */
public class Fail extends AbstractAction {
    @Override
    public void getManResult(Man man) {
        System.out.println("男人对该歌手的评价是失败的!");
    }
    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("女人对该歌手的评价是失败的!");
    }
}
待定评价类
package cn.ppdxzz.visitor;
/**
 * description:待定评价类
 */
public class Wait extends AbstractAction {
    @Override
    public void getManResult(Man man) {
        System.out.println("男人对该歌手的评价是待定...");
    }
    @Override
    public void getWomanResult(Woman woman) {
        System.out.println("女人对该歌手的评价是待定...");
    }
}
数据结构
package cn.ppdxzz.visitor;
import java.util.LinkedList;
import java.util.List;
/**
 * description:数据结构,管理很多人
 */
public class ObjectStructure {
    /**
     * 维护一个集合
     */
    private List<AbstractPerson> personList = new LinkedList<>();
    /**
     * 添加到list集合
     * @param person 人
     */
    public void attach(AbstractPerson person) {
        personList.add(person);
    }
    /**
     * 显示测评情况
     */
    public void display(AbstractAction action) {
        personList.forEach(person -> person.accept(action));
    }
}
访问者模式客户端
package cn.ppdxzz.visitor;
/**
 * description:访问者模式客户端
 */
public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new Man());
        objectStructure.attach(new Woman());
        System.out.println("-------成功的评价--------");
        Success success = new Success();
        objectStructure.display(success);
        System.out.println("-------失败的评价--------");
        Fail fail = new Fail();
        objectStructure.display(fail);
        System.out.println("-------待定的评价--------");
        Wait wait = new Wait();
        objectStructure.display(wait);
    }
}
运行结果:

总结:
- 访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高。
- 如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的。
