按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
这种配置意味着可采取 Visitor 的新子类的形式将新的功能添加到系统里,没必要接触Trash 结构。这就是
“访问器”范式最主要的优点:可为一个类结构添加新的多形性功能,同时不必改动结构——只要安装好了
accept()方法。注意这个优点在这儿是有用的,但并不一定是我们在任何情况下的首选方案。所以在最开始
的时候,就要判断这到底是不是自己需要的方案。
现在注意一件没有做成的事情:访问器方案防止了从主控 Trash 序列向单独类型序列的归类。所以我们可将
所有东西都留在单主控序列中,只需用适当的访问器通过那个序列传递,即可达到希望的目标。尽管这似乎
并非访问器范式的本意,但确实让我们达到了很希望达到的一个目标(避免使用RTTI )。
访问器范式中的双生派遣负责同时判断Trash 以及Visitor 的类型。在下面的例子中,大家可看到Visitor
的两种实现方式:PriceVisitor 用于判断总计及价格,而WeightVisitor 用于跟踪重量。
可以看到,所有这些都是用回收程序一个新的、改进过的版本实现的。而且和DoubleDispatch。java 一样,
Trash 类被保持孤立,并创建一个新接口来添加 accept()方法:
613
…………………………………………………………Page 615……………………………………………………………
//: Visitable。java
// An interface to add visitor functionality to
// the Trash hierarchy without modifying the
// base class。
package c16。trashvisitor;
import c16。trash。*;
interface Visitable {
// The new method:
void accept(Visitor v);
} ///:~
Aluminum ,Paper,Glass 以及Cardboard 的子类型实现了accept()方法:
//: VAluminum。java
// Aluminum for the visitor pattern
package c16。trashvisitor;
import c16。trash。*;
public class VAluminum extends Aluminum
implements Visitable {
public VAluminum(double wt) { super(wt); }
public void accept(Visitor v) {
v。visit(this);
}
} ///:~
//: VPaper。java
// Paper for the visitor pattern
package c16。trashvisitor;
import c16。trash。*;
public class VPaper extends Paper
implements Visitable {
public VPaper(double wt) { super(wt); }
public void accept(Visitor v) {
v。visit(this);
}
} ///:~
//: VGlass。java
// Glass for the visitor pattern
package c16。trashvisitor;
import c16。trash。*;
public class VGlass extends Glass
implements Visitable {
public VGlass(double wt) { super(wt); }
public void accept(Visitor v) {
v。visit(this);
}
} ///:~
//: VCardboard。java
614
…………………………………………………………Page 616……………………………………………………………
// Cardboard for the visitor pattern
package c16。trashvisitor;
import c16。trash。*;
public class VCardboard extends Cardboard
implements Visitable {
public VCardboard(double wt) { super(wt); }
public void accept(Visitor v) {
v。visit(this);
}
} ///:~
由于Visitor 基础类没有什么需要实在的东西,可将其创建成一个接口:
//: Visitor。java
// The base interface for visitors
package c16。trashvisitor;
import c16。trash。*;
interface Visitor {
void visit(VAluminum a);
void visit(VPaper p);
void visit(VGlass g);
void visit(VCardboard c);
} ///:~
Once again custom Trash types have been created in a different subdirectory。 The new Trash data
file is VTrash。dat and looks like this:
c16。TrashVisitor。VGlass:54
c16。TrashVisitor。VPaper:22
c16。TrashVisitor。VPaper:11
c16。TrashVisitor。VGlass:17
c16。TrashVisitor。VAluminum:89
c16。TrashVisitor。VPaper:88
c16。TrashVisitor。VAluminum:76
c16。TrashVisitor。VCardboard:96
c16。TrashVisitor。VAluminum:25
c16。TrashVisitor。VAluminum:34
c16。TrashVisitor。VGlass:11
c16。TrashVisitor。VGlass:68
c16。TrashVisitor。VGlass:43
c16。TrashVisitor。VAluminum:27
c16。TrashVisitor。VCardboard:44
c16。TrashVisitor。VAluminum:18
c16。TrashVisitor。VPaper:91
c16。TrashVisitor。VGlass:63
c16。TrashVisitor。VGlass:50
c16。TrashVisitor。VGlass:80
c16。TrashVisitor。VAluminum:81
c16。TrashVisitor。VCardboard:12
c16。TrashVisitor。VGlass:12
615
…………………………………………………………Page 617……………………………………………………………
c16。TrashVisitor。VGlass:54
c16。TrashVisitor。VAluminum:36
c16。TrashVisitor。VAluminum:93
c16。TrashVisitor。VGlass:93
c16。TrashVisitor。VPaper:80
c16。TrashVisitor。VGlass:36
c16。TrashVisitor。VGlass:12
c16。TrashVisitor。VGlass:60
c16。TrashVisitor。VPaper:66
c16。TrashVisitor。VAluminum:36
c16。TrashVisitor。VCardboard:22
程序剩余的部分将创建特定的 Visitor 类型,并通过一个 Trash 对象列表发送它们:
//: TrashVisitor。java
// The 〃visitor〃 pattern
package c16。trashvisitor;
import c16。trash。*;
import java。util。*;
// Specific group of algorithms packaged
// in each implementation of Visitor:
class PriceVisitor implements Visitor {
private double alSum; // Aluminum
private double pSum; // Paper
private double gSum; // Glass
private double cSum; // Cardboard
public void visit(VAluminum al) {
double v = al。weight() * al。value();
System。out。println(
〃value of Aluminum= 〃 + v);
alSum += v;
}
public void visit(VPaper p) {
double v = p。weight() * p。value();
System。out。println(
〃value of Paper= 〃 + v);
pSum += v;
}
public void visit(VGlass g) {
double v = g。weight() * g。value();
System。out。println(
〃value of Glass= 〃 + v);
gSum += v;
}
public void visit(VCardboard c) {
double v = c。weight() * c。value() ;
System。out。println(
〃value of Cardboard = 〃 + v);
cSum += v;
}
void total() {
616
…………………………………………………………Page 618……………………………………………………………
System。out。println(
〃Total Aluminum: 〃 + alSum + 〃n〃 +
〃Total Paper: 〃 + pSum + 〃n〃 +
〃Total Glass: 〃 + gSum + 〃n〃 +
〃Total Cardboard: 〃 + cSum);
}
}
class WeightVisitor implements Visitor {
private double alSum; // Aluminum
private double pSum; // Paper
private double gSum; // Glass
private double cSum; // Cardboard
public void visit(VAluminum al) {
alSum += al。weight();
System。out。println(〃weight of Aluminum = 〃
+ al。weight());
}
public void visit(VPaper p) {
pSum += p。weight();
System。out。println(〃weight of Paper = 〃
+ p。weight());
}
public void visit(VGlass g) {
gSum += g。weight();
System。out。println(〃weight of Glass = 〃
+ g。weight());
}
public void visit(VCardboard c) {
cSum += c。weight();
System。out。println(〃weight of Cardboard = 〃
+ c。weight());
}
void total() {
System。out。println(〃Total weight Aluminum:〃
+ alSum);
System。out。println(〃Total weight Paper:〃
+ pSum);
System。out。println(〃Total weight Glass:〃
+ gSum);
System。out。println(〃Total weight Cardboard:〃
+ cSum);
}
}
public class TrashVisitor {
public static void main(String'' args) {
Vector bin = new Vector();
// ParseTrash still works; without changes:
ParseTrash。fillBin(〃VTrash。dat〃; bin);
// You could even iterate through
// a list of visitors!
617
…………………………………………………………Page 619……………………………………………………………
PriceVisitor pv = new PriceVisitor();
WeightVisitor wv = new WeightVisitor();
Enumeration it = bin。elements();
while(it。hasMoreElemen