核心模块:抽象访问者、具体访问者、抽象元素、具体元素、对象结构
所有代码请访问:git@code.aliyun.com:289804201/PatternLearn.git
目的:封装一些施加于某种数据元上上的操作,使不改变元素类的情况下定义作用于这个元素的新操作;
使用场景:数据元很少改变,但是数据元上的操作经常改变;
优点:方便添加新操作,有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中;
缺点:新增元素困难,因为要在抽象访问者中新增访问方法;
注意:
1,用于结构很少变化的系统中;
2,对象结构中存储了不同类型的元素对象,其基类是抽象元素,一般要遍历list或者map;
/**
* Created by tory on 2017/12/5.
* 访问者模式
*/
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.addElement(new ConcreteElementNodeA());
os.addElement(new ConcreteElementNodeB());
os.action(new ConcreteVisitorA());
os.action(new ConcreteVisitorB());
}
}
//实用场景:1,对同一个对象有不同的使用场景;比如药房和收费两个访问者对药品的访问;不同的访问者与元素类关系不大,但是是一个易变的操作
//2,适用于数据结构相对稳定的系统
//特性:访问者可以扩展,元素类可扩展
//抽象访问者
interface IVisitor {
//定义访问者可以访问哪些元素
// FIXME: 2017/12/5 参数为可以扩展,访问者层次扩展
void visit(ConcreteElementNodeA node);
void visit(ConcreteElementNodeB node);
}
//具体访问者A
class ConcreteVisitorA implements IVisitor {
//它影响到访问者访问到一个类后该干什么
@Override
public void visit(ConcreteElementNodeA node) {
//拿到对象A后做什么操作
System.out.println("我是访问者A");
System.out.println("fuck"+node.operationA());
}
@Override
public void visit(ConcreteElementNodeB node) {
//拿到对象B后做什么
System.out.println("我是访问者A");
System.out.println("去你妈的"+node.operationB());
}
}
//具体访问者A
class ConcreteVisitorB implements IVisitor {
@Override
public void visit(ConcreteElementNodeA node) {
System.out.println("我是访问者B");
System.out.println("hello" + node.operationA());
}
@Override
public void visit(ConcreteElementNodeB node) {
System.out.println("我是访问者B");
System.out.println("你好" + node.operationB());
}
}
//抽象元素类,声明接受哪一类访问者访问
abstract class ElementNode {
//这里为接受Visitor这一类访问者,元素类可扩展
abstract void accept(IVisitor visitor);
}
//具体元素A
class ConcreteElementNodeA extends ElementNode {
@Override
void accept(IVisitor visitor) {
//IVisitor代表不同的访问者对元素A的访问
visitor.visit(this);
}
String operationA() {
return ConcreteElementNodeA.class.getSimpleName();
}
}
//具体元素B
class ConcreteElementNodeB extends ElementNode {
@Override
void accept(IVisitor visitor) {
//IVisitor代表不同的访问者对元素B的访问
visitor.visit(this);
}
String operationB() {
return ConcreteElementNodeB.class.getSimpleName();
}
}
//存储了不同类型的元素对象,以便变不同的访问者访问
class ObjectStructure {
private List<ElementNode> list = new ArrayList<>();
void action(IVisitor visitor) {
for (ElementNode node : list) {
node.accept(visitor);
}
}
void addElement(ElementNode node) {
list.add(node);
}
}
内容打印
Hello World!
我是访问者A
fuckConcreteElementNodeA
我是访问者A
去你妈的ConcreteElementNodeB
我是访问者B
helloConcreteElementNodeA
我是访问者B
你好ConcreteElementNodeB