title: 访问者模式
author: rack-leen
avatar: /images/favicon.png
authorDesc: 脱发典范
comments: true
copyright: true
date: 2019-5-19 22:13:39
tags:
Represent an operation to be performed on the elements of an objects structure.Vistor lets you define a new operation without changing the classes of the elements on which it operates.
封装一些作用于某种数据结构中的各元素操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

/**
 * 元素的抽象类,定义所有元素共同操作
 */
public abstract class Element {
    /* 元素的动作 */
    public abstract void test();
    /* 元素接受访问者访问,访问者可以在自己那里定义访问动作 */
    public abstract void accept(IVisitor visitor);
}
/**
 * 元素1的实现类
 */
public class ConcreteElement1 extends Element {
    @Override
    public void test() {
        System.out.println("元素1");
    }
    /**
     * 接受访问者的访问,并将产生的元素对象送给访问者,让访问者操作元素对象
     * @param visitor
     */
    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}
/**
 * 元素2的实现类
 */
public class ConcreteElement2 extends Element{
    @Override
    public void test() {
        System.out.println("元素2");
    }
    /**
     * 接受访问者的访问,将元素2的对象送给访问者,让访问者能操作元素2的对象
     * @param visitor
     */
    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}
/**
 * 访问者接口
 */
public interface IVisitor {
    /* 用于访问元素1 */
    public void visit(ConcreteElement1 element1);
    /* 用于访问元素2 */
    public void visit(ConcreteElement2 element2);
}
/**
 * 访问者
 */
public class ConcreteVisitor implements IVisitor {
    /**
     * 访问者访问元素1的方法,元素1接受了访问者的访问,访问者能够获取到元素1的对象,然后在这个方法中自由操作元素对象
     * @param element1
     */
    @Override
    public void visit(ConcreteElement1 element1) {
        element1.test();
    }
    /**
     * 访问者访问元素2的方法,元素1接受了访问者的访问,访问者能够获取到元素2的对象,然后在这个方法中自由操作元素对象
     * @param element2
     */
    @Override
    public void visit(ConcreteElement2 element2) {
        element2.test();
    }
}
/**
 * 对象结构,用来生产元素对象,这里随机生产出元素1或者元素2
 */
public class ObjectStructure {
    public static Element createElement(){
        Random random = new Random();
        if (random.nextInt(100) > 50) {
            return new ConcreteElement1();
        }else {
            return new ConcreteElement2();
        }
    }
}
public class Test{
	public static void main(String[] args) {
	        for (int i=0 ; i<10 ; i++){
            /* 创建元素对象 */
            Element element = ObjectStructure.createElement();
            /* 让元素接受访问者的访问 */
            /* 接受访问后,访问者就获取元素对象,操作元素对象 */
            element.accept(new ConcreteVisitor());
        }
	}
}