首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

举动型设计模式之VISITOR模式

2012-10-24 
行为型设计模式之VISITOR模式访问者模式:作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象

行为型设计模式之VISITOR模式
访问者模式:
作用于某个对象群中各个对象的操作.
它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.

否则的话,我们的做法:
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
   Object o = iterator.next();
   if (o instanceof Collection)
      messyPrintCollection((Collection)o);
   else if (o instanceof String)
      System.out.println("'"+o.toString()+"'");
   else if (o instanceof Float)
      System.out.println(o.toString()+"f");
   else
      System.out.println(o.toString());
}
我们要使用 instanceof 来确定具体类型,然后调用具体的对象方法。

我们该如何使用呢:
   1. Add an accept(Visitor) method to the “element” hierarchy
   2. Create a “visitor” base class w/ a visit() method for every “element” type
   3. Create a “visitor” derived class for each “operation” to do on “elements”
   4. Client creates “visitor” objects and passes each to accept() calls

首先我们要确定一个可以供访问每个对象(即上面描述中的Collection中的Element)的接口Visitable:
public interface Visitable{
    public void accept(Visitor visitor);
}

我们可以通过这个接口来使得我们集合中的每个对象(Element)接收一个具体visitor的访问。
接着我们就可以创建一个访问每个对象(Element)的Visitor接口:
public interface Visitor{
    //在这个Visitor中,要增加访问Collection中各种Elements的具体方法,所以
    //有个前提条件就是Visitor要知道你的所有的Elements的种类。
    public viod visitElementType1(ElementType1 e);
    public viod visitElementType2(ElementType2 e);
    public viod visitElementType3(ElementType3 e);
    ......
    public viod visitElementTypeN(ElementTypeN e);
}
有了上面的准备我们就要开始动手来点实际的了:
//具体访问每个类型的Element的方法实现。
public class ConcreteVisitor implements Visitor{
    public viod visitElementType1(ElementType1 e){
         //visit this object by concrete method by the api
    };
    public viod visitElementType2(ElementType2 e){
//visit this object by concrete method by the api
    }
    ......

}
public class AnotherConcreteVisitor implements Visitor{
    public viod visitElementType1(ElementType1 e){
         //visit this object by concrete method by the api
    };
    public viod visitElementType2(ElementType2 e){
//visit this object by concrete method by the api
    }
    ......

}
//下面是我们要封装的集合里面的Elements
public class ElementType1 implements Visitable{
    //其他不管,这个方法才是关键
    public void accept(Visitor visitor){
        visitor.visitElementType1(this);
    }
}

public class ElementType2 implements Visitable{

    public void accept(Visitor visitor){
        visitor.visitElementType2(this);
    }
}
......
上面的实现方式不知道看明白没有,我在这里是有意用visitElementType2这种方式定义方法,实际上我们
也可以采用重载一个方法visit(ElementType1 e),visit(ElementType2 e),......,visit(ElementTypeN e)
这样我们可以调用统一的方法了:
public class ElementType1 implements Visitable{

    public void accept(Visitor visitor){
        visitor.visit(this);//这个地方你就不用担心具体类型了
    }
}

该有的我们都已经有了,现在是不是可以看看调用方式了呢:
class VisitorDemo {
   public static Element[] list = { new ElementType1(), new ElementType2(),....., new ElementTypeN() };

   // Client creates "visitor" objects and passes each to accept() calls
   public static void main( String[] args ) {
      ConcreteVisitor    up   = new ConcreteVisitor();
      AnotherConcreteVisitor   down   = new AnotherConcreteVisitor();
      for (int i=0; i < list.length; i++) {
         list[i].accept( up );//这里就是访问函数的入口,对每一个元素对象访问都委托给了Visitor的相应visit方法
      }
      for (int i=0; i < list.length; i++) {
         list[i].accept( down );//对于不同的访问规则,可以有多个具体Visitor实现
      }
   }
}

不管怎么说,这个学习和整理过程算是“吃百家饭”出来的!
各位有什么宝贵意见,望不吝发表啊!!

热点排行