//在本方法中,我们实现了对Collection 的元素的成功访问</p> public void visitCollection(Collection collection) {
( j% X* E) m1 y8 P( j# c Iterator iterator = collection.iterator()
4 n8 R6 U }& d4 w ^ while (iterator.hasNext()) {
2 z1 \* O S, e8 {: U Object o = iterator.next();' v2 r0 F, Z9 B# \+ ]. u
if (o instanceof Visitable)
( I3 E$ J# Z+ D. ?1 c, q0 m ((Visitable)o).accept(this);% E ]- h5 B; R# ~
}
4 }# x) m" M- E" d; c public void visitString(String string) {
, ]' Z" n. K1 a" C/ s/ R; N System.out.println("'"+string+"'");
, i0 {, y3 n: ?& A/ K/ H8 O6 S% z }
5 ~( S3 O% _4 R) C* q4 l public void visitFloat(Float float) {$ r' _% p R- U8 z8 Y3 p7 K( O' q
System.out.println(float.toString()+"f");
, Z1 s0 B' r( m }
0 e" Z6 d1 j/ d8 k } P1 u L9 H+ Y' _5 d
}
x0 d6 j# D( ^: R; b6 T# w3 D$ d 在上面的visitCollection 我们实现了对Collection 每个元素访问,只使用了一个判断语句,只要判断其是否可以访问.
: y H5 ?- {, B6 X8 B9 A8 x 至此,我们完成了Visitor 模式基本架构.
8 A3 Z J# k3 y5 i 使用Visitor 模式的前提
9 g4 U: M( P' P- K7 o8 J& Y 对象群结构中(Collection) 中的对象类型很少改变,也就是说访问者的身份类型很少改变,如上面中Visitor 中的类型很少改变,如果需要增加新的操作,比如上例中我们在ConcreteElement 具体实现外,还需要新的ConcreteElement2 ConcreteElement3.
. [) x2 }' J+ i: x 可见使用Visitor 模式是有前提的,在两个接口Visitor 和Visitable 中,确保Visitor 很少变化,变化的是Visitable,这样使用Visitor 最方便.
1 \$ O0 ?$ ~) |# P* b. r 如果Visitor 也经常变化, 也就是说,对象群中的对象类型经常改变,一般建议是,不如在这些对象类中逐个定义操作.但是Java 的Reflect 技术解决了这个问题.
6 _: J0 w+ N4 g; N1 R- \3 W1 i8 m Reflect 技术是在运行期间动态获取对象类型和方法的一种技术,具体实现参考Javaworld的英文原文. |