java设计模式 访问者模式

    技术2024-10-14  60

       设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Visitor(访问者)模式是比较常用的一个模式.   应用场景:对于某对象结构中各元素的操作。如果需要在不修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法应该考虑访问者模式。   想让数个不同的访问者对同一个对象集合进行访问时,Visitor模式可以发挥它的强大作用。Visitor先调用了Visitable类中的方法,这个方法又回调到Visitor类中     在此写了10个java类来描述说明Visitor设计模式;  1、 NodeA.java  可访问节点A  2、 NodeB.java  可访问节点B  3、 NodeC.java  可访问节点C  4、 Visitable.java 可访问对象接口  5、 Visitor.java  访问者接口  6、 VisitorA.java  访问者A  7、 VisitorTest.java  带有main方法的测试类  5变体、 Visitor.java  访问者接口(应用java反射机制)  6变体、 VisitorA.java  访问者A(应用java反射机制)  7变体、 VisitorTest.java  带有main方法的测试类(应用java反射机制)

     

    ===============   1、 NodeA.javapackage visitor;public class NodeA implements Visitable {  public void accept(Visitor visitor) {    visitor.visit(this);  }}===============   1 end

     

    ===============   2、 NodeB.javapackage visitor;public class NodeB implements Visitable {  public void accept(Visitor visitor) {    visitor.visit(this);  }}===============   2 end

     

    ===============   3、 NodeC.javapackage visitor;public class NodeC implements Visitable {  public void accept(Visitor visitor) {    visitor.visit(this);  }}===============   3 end

     

    ===============   4、 Visitable.javapackage visitor;public interface Visitable {   public void accept(Visitor visitor);}===============   4 end

     

    ===============   5、 Visitor.javapackage visitor;import java.util.Collection;public interface Visitor {  //访问节点A  public void visit(NodeA nodeA);  //访问节点B  public void visit(NodeB nodeB);  //访问节点C  public void visit(NodeC nodeC);  //访问节点集合  public void visitCollection(Collection  collection); }===============   5 end

     

    ===============   6、 VisitorA.javapackage visitor;import java.util.Collection;import java.util.Iterator;public class VisitorA implements Visitor {  public void visit(NodeA a){    System.out.println("Execute visitNodeA method!");;  }  public void visit(NodeB b){    System.out.println("Execute visitNodeB method!");;  }  public void visit(NodeC c){    System.out.println("Execute visitNodeC method!");;  }  public void visitCollection(Collection collection){    Iterator iterator = collection.iterator();    while (iterator.hasNext()) {      Object o = iterator.next();      if (o instanceof Visitable)        ((Visitable)o).accept(this);      }  }}===============   6 end ===============   7、 VisitorTest.javapackage visitor;import java.util.ArrayList;import java.util.List;public class VisitorTest {  public static void main(String[] args) {    NodeA nodeA = new NodeA();    NodeB nodeB = new NodeB();    NodeC nodeC = new NodeC();    VisitorTest nodeD = new VisitorTest();    //访问单个对象    VisitorA visitorA = new VisitorA();    visitorA.visit(nodeA);    visitorA.visit(nodeB);    visitorA.visit(nodeC);    //访问集合    List<Visitable> list = new ArrayList<Visitable>();    list.add(nodeA);    list.add(nodeB);    list.add(nodeC);    visitorA.visitCollection(list);  }}===============   7 end

     

      在两个接口Visitor和Visitable中,确保Visitable很少变化,也就是说,确保不能老有新的Element元素类型加进来,可以变化的是访问者行为或操作,也就是Visitor的不同子类可以有多种,这样使用访问者模式最方便.  当然采用java反射机制, 可以使对象集合中的对象经常有变化。

     

     采用java反射机制的  Visitor 变体

      采用了java反射机制的vistor变体,类1,2,3,4 均不变  通过使用Java Reflection,可以增强Visitor模式,使之具有操作对象结构的强大功能,并在增加新Visitable类型方面提供灵活性。===============   5变体、 Visitor.javapackage visitor;public interface Visitor { //访问者触发的方法 public void visit(Object o);}===============   5变体 end

     

    ===============   6变体、 VisitorA.javapackage visitor;import java.lang.reflect.Method;import java.util.AbstractCollection;import java.util.Iterator;public class VisitorA implements Visitor { public void visitObject(Object o) {  System.out.println("Execute visitObject method!");; } public void visitNodeA(NodeA a){  System.out.println("Execute visitNodeA method!");; } public void visitNodeB(NodeB b){  System.out.println("Execute visitNodeB method!");; } public void visitNodeC(NodeC c){  System.out.println("Execute visitNodeC method!");; } public void visitAbstractCollection(AbstractCollection<Visitable> collection){  Iterator<Visitable> iterator = collection.iterator();  while(iterator.hasNext()){   iterator.next().accept(this);  } }  //对o元素进行访问 public void visit(Object o){  try {   //1 Get the method of visitor needed to call   Method m = getMethod(o.getClass());   //2 execute the method   m.invoke(this, new Object[]{o});  } catch (Exception e) {   // TODO: handle exception   e.printStackTrace();  } }

      //根据传进来的类名获得访问者需要执行的方法  protected Method getMethod(Class c) {    Class newc = c;    Method m = null;       //根据传进来的类名去寻找相应的方法,如果不从在就去超类中找    String method = null;    while (m == null && newc != Object.class) {      method = "visit" + newc.getSimpleName();      try {        m = getClass().getMethod(method, new Class[] {newc});      } catch (NoSuchMethodException e) {        newc = newc.getSuperclass();      }    }       //如果超类是Object,则到接口中找    if (newc == Object.class) {      Class[] interfaces = c.getInterfaces();      for (int i = 0; i < interfaces.length; i++) {        method = "visit" + interfaces[i].getSimpleName();        try {          m = getClass().getMethod(method, new Class[] {interfaces[i]});        } catch (NoSuchMethodException e) {}      }    }       //如果m==null,则执行visitor中默认的方法    if (m == null) {      try {        m = this.getClass().getMethod("visitObject", new Class[] {Object.class});      } catch (Exception e) {}    }       return m;  }

    }===============   6变体 end ===============   7变体、 VisitorTest.javapackage visitor;import java.util.ArrayList;import java.util.List;public class VisitorTest { public static void main(String[] args) {  NodeA nodeA = new NodeA();  NodeB nodeB = new NodeB();  NodeC nodeC = new NodeC();  VisitorTest nodeD = new VisitorTest();  //访问单个对象  VisitorA visitorA = new VisitorA();  visitorA.visit(nodeA);  visitorA.visit(nodeB);  visitorA.visit(nodeC);  visitorA.visit(nodeD);  //访问集合  List<Visitable> list = new ArrayList<Visitable>();  list.add(nodeA);  list.add(nodeB);  list.add(nodeC);  visitorA.visit(list); }}===============   7变体 end

    最新回复(0)