《JAVA与模式》第24天―访问者模式 (四)

2014-11-24 08:31:47 · 作者: · 浏览: 4
t) {

System.out.println("SubWest2 + " + east.myName2());
}
}
public class SubWest2 extends West{
@Override
public void goWest1(SubEast1 east) {

System.out.println("SubWest2 + " + east.myName1());
}

@Override
public void goWest2(SubEast2 east) {

System.out.println("SubWest2 + " + east.myName2());
}
}

 East类

[java]
public abstract class East {

public abstract void goEast(West west);
}
public abstract class East {

public abstract void goEast(West west);
}

  SubEast1类

[java]
public class SubEast1 extends East{
@Override
public void goEast(West west) {
west.goWest1(this);
}

public String myName1(){
return "SubEast1";
}
}
public class SubEast1 extends East{
@Override
public void goEast(West west) {
west.goWest1(this);
}

public String myName1(){
return "SubEast1";
}
}

  SubEast2类

[java]
public class SubEast2 extends East{
@Override
public void goEast(West west) {
west.goWest2(this);
}

public String myName2(){
return "SubEast2";
}
}
public class SubEast2 extends East{
@Override
public void goEast(West west) {
west.goWest2(this);
}

public String myName2(){
return "SubEast2";
}
}

  客户端类

[java]
public class Client {

public static void main(String[] args) {
//组合1
East east = new SubEast1();
West west = new SubWest1();
east.goEast(west);
//组合2
east = new SubEast1();
west = new SubWest2();
east.goEast(west);
}

}
public class Client {

public static void main(String[] args) {
//组合1
East east = new SubEast1();
West west = new SubWest1();
east.goEast(west);
//组合2
east = new SubEast1();
west = new SubWest2();
east.goEast(west);
}

}

运行结果如下

--------------------------------------------------------------------------------  
SubWest1 + SubEast1
SubWest2 + SubEast1
--------------------------------------------------------------------------------


  系统运行时,会首先创建SubWest1和SubEast1对象,然后客户端调用SubEast1的goEast()方法,并将SubWest1对象传入。由于SubEast1对象重写了其超类East的goEast()方法,因此,这个时候就发生了一次动态的单分派。当SubEast1对象接到调用时,会从参数中得到SubWest1对象,所以它就立即调用这个对象的goWest1()方法,并将自己传入。由于SubEast1对象有权选择调用哪一个对象,因此,在此时又进行一次动态的方法分派。

  这个时候SubWest1对象就得到了SubEast1对象。通过调用这个对象myName1()方法,就可以打印出自己的名字和SubEast对象的名字,其时序图如下所示:

\

  由于这两个名字一个来自East等级结构,另一个来自West等级结构中,因此,它们的组合式是动态决定的。这就是动态双重分派的实现机制。

访问者模式的结构
  访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。访问者模式的简略图如下所示:

\

数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象,而访问者对象则反过来执行节点对象的操作。这样的过程叫做“双重分派”。节点调用访问者,将它自己传入,访问者则将某算法针对此节点执行。访问者模式的示意性类图如下所示:

\

  访问者模式涉及到的角色如下:

  ●  抽象访问者(Visitor)角色:声明了一个或者多个方法操作,形成所有的具体访问者角色必须实现的接口。

  ●  具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作。

  ●  抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参数。

  ●  具体节点(ConcreteNode)角色:实现了抽象节点所规定的接受操作。

  ●  结构对象(ObjectStructure)角色:有如下的责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如List或Set。

  源代码
  可以看到,抽象访问者角色为每一个具体节点都准备了一个访问操作。由于有两个节点,因此,对应就有两个访问操作。

[java]
package com.bankht.Visitor.visitor;

/**
* @author: 特种兵—AK47
* @创建时间:2012-7-3 上午10:50:06
*
* @类说明 :可以看到,抽象访问