Visitor模式的組成結構:
1) 訪問者角色(Visitor):聲明一個訪問接口。接口的名稱和方法的參數標識了向訪問者發送請求的元素角色。這樣訪問者就可以通過該元素角色的特定接口直接訪問它。
2) 具體訪問者角色(Concrete Visitor):實現訪問者角色(Visitor)接口
3) 元素角色(Element):定義一個Accept操作,它以一個訪問者爲參數。
4) 具體元素角色(Concrete Element):實現元素角色(Element)接口。
5) 對象結構角色(Object Structure):這是使用Visitor模式必須的角色。它要具備以下特徵:能枚舉它的元素;可以提供一個高層的接口允許訪問者角色訪問它的元素;可以是一個組合(組合模式)或是一個集合,如一個列表或一個無序集合。
類圖如下:
代碼例子:
void visit(Gladiolus g);
void visit(Runuculus r);
void visit(Chrysanthemum c);
}
interface Flower {
void accept(Visitor v);
}
// concrete element
class Gladiolus implements Flower {
public void accept(Visitor v) { v.visit(this);}
}
class Runuculus implements Flower {
public void accept(Visitor v) { v.visit(this);}
}
class Chrysanthemum implements Flower {
public void accept(Visitor v) { v.visit(this);}
}
// concrete visitor
class StringVal implements Visitor {
String s;
public String toString() { return s; }
public void visit(Gladiolus g) {
s = "Gladiolus";
}
public void visit(Runuculus r) {
s = "Runuculus";
}
public void visit(Chrysanthemum c) {
s = "Chrysanthemum";
}
}
// concrete visitor
class Bee implements Visitor {
public void visit(Gladiolus g) {
System.out.println("Bee and Gladiolus");
}
public void visit(Runuculus r) {
System.out.println("Bee and Runuculus");
}
public void visit(Chrysanthemum c) {
System.out.println("Bee and Chrysanthemum");
}
}
//這是一個對象生成器
class FlowerGenerator {
private static Random rand = new Random();
public static Flower newFlower() {
switch(rand.nextInt(3)) {
default:
case 0: return new Gladiolus();
case 1: return new Runuculus();
case 2: return new Chrysanthemum();
}
}
}
//客戶測試程序
public class BeeAndFlowers extends TestCase {
/*
首先在客戶端先獲得一個具體的訪問者角色
遍歷對象結構
對每一個元素調用accept方法,將具體訪問者角色傳入
這樣就完成了整個過程
*/
List flowers = new ArrayList();
public BeeAndFlowers() {
for(int i = 0; i < 10; i++)
flowers.add(FlowerGenerator.newFlower());
}
Visitor sval ;
public void test() {
sval = new StringVal();
Iterator it = flowers.iterator();
while(it.hasNext()) {
((Flower)it.next()).accept(sval);
System.out.println(sval);
}
}
public static void main(String args[]) {
junit.textui.TestRunner.run(BeeAndFlowers.class);
}
}