行为型设计模式之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实现
}
}
}
不管怎么说,这个学习和整理过程算是“吃百家饭”出来的!
各位有什么宝贵意见,望不吝发表啊!!