学习访问者模式,写下一些浅显的认识。
访问者模式可以将一个数据结构(一个类)的自身结构与对这个数据结构(类)的操作进行一定的分离。而操作就交与访问者进行处理。
访问者模式使用于结构比较稳定的类。
//====================
来实现应用访问者模式的一个小例子:
首先需要一个节点接口,该接口用有一个accept方法,参数是一个访问者接口,因为该节点时要被访问的,这个方法的作用就是指派该节点被谁(也就是哪个visitor)来访问。而参数的类型是一个接口,因为访问者的具体类型是可以变化的,这样就可以对节点进行多种操作了。
package visitor; public abstract class INode { abstract public void accept(IVisitor v); }
再写一个访问者接口,其实就是对节点进行操作的接口。该接口中有一个visit方法,其作用是指明访问者应该去访问哪个具体的节点。参数不能设置为一个接口类型,因为在调用方法的时候是调用具体的方法。IVisitor类应该是一个结构稳定的。也就是说对于node来讲它的实现是有限的,固定的。
package visitor; public abstract class IVisitor { public abstract void visit(NodeImpA a); public abstract void visit(NodeImpB b); // 在此处不能以接口作为参数传入,因为在调用的时候会根据具体的类进行方法调用 // public abstract void visit(INode node); }
下面实现INode接口,在accep方法中调用了IVisitor的visit方法,该方法接受的参数是一个具体的Node(NodeImpA/NodeImpB),所以v就会来指派应该调用IVisitor的哪个具体的visit方法。
package visitor; public class NodeImpA extends INode { public void accept(IVisitor v) { v.visit(this); } public String actionA(){ return "NodeImpA has be visited"; } }
package visitor; public class NodeImpB extends INode { public void accept(IVisitor v) { v.visit(this); } public String actionA() { return "NodeImpB has be visited"; } }
实现IVisitor接口,IVisitor中参数的传递都是以具体的类型进行传递的,这样在NodeImpA或NodeImpB传递this的时候就可以判断需要调用什么visit方法了,
package visitor; public class VisitorImpA extends IVisitor { @Override public void visit(NodeImpA a) { System.out.println("VisitorImpA :" + a.actionA()); } @Override public void visit(NodeImpB b) { System.out.println("VisitorImpA :" + b.actionA()); } }
package visitor; public class VisitorImpB extends IVisitor { @Override public void visit(NodeImpA a) { System.out.println("VisitorImpB :" + a.actionA()); } @Override public void visit(NodeImpB b) { System.out.println("VisitorImpB :" + b.actionA()); } }
该模式需要一个管理的类,可以遍历结构中的所有元素。
package visitor; import java.util.ArrayList; import java.util.List; public class ObjectStructure { private List<INode> nodes = new ArrayList<INode>(); public void add(INode node){ nodes.add(node); } public void manager(IVisitor v){ for(INode node : nodes){ node.accept(v); } } public static void main(String[] args) { INode a = new NodeImpA(); INode b = new NodeImpB(); ObjectStructure manager = new ObjectStructure(); manager.add(a); manager.add(b); IVisitor va = new VisitorImpA(); IVisitor vb = new VisitorImpB(); manager.manager(va); manager.manager(vb); } }
若我们需要对节点进行更多的操作,可以增加一个实现IVisitor的具体类。而对节点不做改动。但是如果节点发生了变化,这样访问者模式就会难以对付。
http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html