Java设计模式之Visitor

    访问者模式(Visitor)
   Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在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.java
package visitor;
public class NodeA implements Visitable {
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}
===============   1 end

 

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

 

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

 

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

 

===============   5、 Visitor.java
package 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.java
package 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.java
package 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.java
package visitor;
public interface Visitor {
 //访问者触发的方法
 public void visit(Object o);
}
===============   5变体 end

 

===============   6变体、 VisitorA.java
package 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.java
package 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

你可能感兴趣的:(java,设计模式,object,iterator,Class,interface)