访问者(Visitor)模式【行为模式第六篇】
访问者(Visitor)模式:
访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作要修改的话,接受这个操作的数据
结构则 可以保持不变。
聚集是的大多数的系统都要处理一种容器对象,它保存了对其他对象的引用。相信大多数读者都有处理聚集的经验,但是人家处理过的大多数聚集
恐怕 都是同类操作,而迭代子模式就是为这种情况准备的设计模式。
如果需要针对一个包含不同类型元素的聚集采取某种操作,而操作的细节根据元素的类型不同而有所不同时,就会出现必须对元素类型做类型判断
的条件转移语句。
一、访问者模式涉及到抽象访问者角色、具体访问者角色、抽象节点角色、具体节点角色、结构对象角色以及客户端角色。
1、抽象访问者角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
2、具体访问者角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
3、抽象节点角色:声明一个接受操作,接受一个访问者对象作为一个参量。
4、具体节点角色:实现了抽象元素所规定的接受操作。
5、结构对象角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素
如果需要,可以设计成一个复合对象或者一个聚集。
//抽象访问者角色 public interface Visitor{ //对于NodeA的访问操作 void visit(NodeA node); //对于NodeB的访问操作 void visit(NodeB node); } //具体访问者角色 public class VisitorA implements Visitor{ //对应于NodeA的访问操作 public void visit(NodeA nodeA){ System.out.println(nodeA.operationA()); } //对应于NodeB的访问操作 public void visit(NodeB nodeB){ System.out.println(nodeB.operationB()); } } public class VisitorB implements Visitor{ //对应于NodeA的访问操作 public void visit(NodeA nodeA){ System.out.println(nodeA.operationA()); } //对应于NodeB的访问操作 public void visit(NodeB nodeB){ System.out.println(nodeB.operationB()); } } //抽象节点角色 public abstract class Node{ //接受操作 public abstract void accept(Visitor visitor); } //模式中具体节点NodeA角色 public class NodeA extends Node{ //接受操作 public void accept(Visitor visitor){ visitor.visit(this); } //NodeA特有的商业方法 public String operationA(){ return "NodeA is visited."; } } public class NodeB extends Node{ //接受操作 public void accept(Visitor visitor){ visitor.visit(this); } //NodeA特有的商业方法 public String operationB(){ return "NodeB is visited."; } } //模式中结构对象ObjectStructure import java.util.Vector; import java.util.Enumeration; public class ObjectStructure{ private Vector nodes; private Node node; public ObjectStructure(){ nodes = new Vector(); } //执行访问操作 public void action(Visitor visitor){ for(Enumeration e = nodes.elements(); e.hasMoreElements();){ node = (Node)e.nextElement(); node.accept(visitor); } } //增加一个新的元素 public void add(Node node){ nodes.addElements(node); } } //客户端 public class Client{ private static ObjectStructure aObjects; private static Visitor visitor; public static void main(String args[]){ //创建一个结构对象 aObjects = new ObjectStruture(); //给结构增加一个节点 aObjects.add(new NodeA()); //给结构增加一个节点 aObjects.add(new NodeB()); //创建一个新的访问者 visitor = new VisitorA(); //让访问者访问结构 aObjects.action(visitor); } }//一个电脑专卖系统//抽象访问者角色public abstract class Visitor{public abstract void visitHardDisk(HardDisk e);public abstract void visitMainBoard(MainBoard e);public abstract void visitCpu(Cpu e);public abstract void visitPc(Pc e);public abstract void visitCase(Case e);public abstract void visitIntegratedBoard(IntegratedBoard e);}//具体访问者角色public class PriceVisitor extends Visitor{private float total;public PriceVisitor(){total = 0;}public float value(){return total;}public void visitHardDisk(HardDisk e){total += e.price();}public void visitMainBoard(MainBoard e){total += e.price();}public void visitCpu(Cpu e){total += e.price();}public void visitPc(Pc e){total += e,price();}public void visitCase(Case e){total += e.price();}public void visitIntegratedBoard(IntegratedBoard e){total += e.price();}}//具体访问角色import java.util.Vector;public class InventoryVisitor extends Visitor{private Vector inv;public InventoryVisitor(){inv = new Vector(10.5);}public int size(){return inv.size();}public void visitHardDisk(HardDisk e){inv.addElement(e);}public void visitMainBoard(MainBoard e){inv.addElement(e);}public void visitCpu(Cpu e){inv.addElement(e);}public void visitPc(Pc e){inv.addElement(e);}public void visitCase(Case e){inv.addElement(e);}public void visitIntegratedBoard(IntegratedBoard e){inv.addElement(e);}}//抽象节点角色public abstract class Equipment{//接受方法public abstract void accept(Visitor vis);//商业方法public abstract double price();}//具体节点角色public class MainBoard extends Equipment{public double price(){return 100.00;}public void accept(Visitor v){System.out.println("MainBoard has been visited.");v.visitMainBoard(this);}}//具体节点角色public class HardDisk extends Equipment{public double price(){return 200.00;}public void accept(Visitor v){System.out.println("HardDisk has been visited.");v.visitHardDisk(this);}}//具体节点角色public class Cpu extends Equipment{public double price(){return 800.00;}public void accept(Visitor v){System.out.println("CPU has been visited.");v.visitCpu(this);}}//具体节点角色public class Case extends Equipment{public double price(){return 30.00;}public void accept(Visitor v){System.out.println("Case has been visited.");v.visitCase(this);}}//抽象复合节点public abstract class Composite extends Equipment{private Vector parts = new Vector(10);public Composite(){}public double price(){double total = 0;for(int i = 0; i < parts.size(); i ++){total += ((Equipment)parts.get(i)).price();}return total;}public void accept(Visitor v){for(int i = 0; i < parts.size(); i ++){((Equipment)parts.get(i)).accept(v);}}} //具体复合节点角色 public class IntegratedBoard extends Composite{ public IntegratedBoard(){ super.add(new MainBoard()); super.add(new Cpu()); } public void accept(Visitor v){ System.out.println("IntegratedBoard has been visited."); super.accept(v); } } //具体复合节点角色 public class Pc extends Composite{ public Pc(){ super.add(new IntegratedBoard()); super.add(new HardDisk()); super.add(new Case()); } public void accept(Visitor v){ System.out.println("Pc has been visited."); super.accept(v); } }//客户端public class Client{private static PriceVisitor pv;private static InventoryVisitor iv;private static Equipment equip;public static void main(String args[]){equip = new Pc();pv = new PriceVisitor();equip.accept(pv);System.out.println("Price: " + pv.value());System.out.println();iv = new InventoryVisitor();equip.accept(iv);System.out.println("Number of parts: " + iv.size());}}