>《設(shè)計模式》一書對于訪問者模式給出的定義為:表示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作怒炸。從定義可以看出結(jié)構(gòu)對象是使用訪問者模式必須條件累驮,而且這個結(jié)構(gòu)對象必須存在遍歷自身各個對象的方法擎析。這便類似于java中的collection概念了幸海。
以下是訪問者模式的組成結(jié)構(gòu):
* 1) 訪問者角色(Visitor):為該對象結(jié)構(gòu)中具體元素角色聲明一個訪問操作接口蜜自。該操作接口的名字和參數(shù)標(biāo)識了發(fā)送訪問請求給具體訪問者的具體元素角色诫肠。這樣訪問者就可以通過該元素角色的特定接口直接訪問它司澎。
* 2) 具體訪問者角色(Concrete Visitor):實現(xiàn)每個由訪問者角色(Visitor)聲明的操作欺缘。
* 3) 元素角色(Element):定義一個Accept操作,它以一個訪問者為參數(shù)挤安。
* 4) 具體元素角色(Concrete Element):實現(xiàn)由元素角色提供的Accept操作谚殊。
* 5) 對象結(jié)構(gòu)角色(Object Structure):這是使用訪問者模式必備的角色。它要具備以下特征:能枚舉它的元素蛤铜;可以提供一個高層的接口以允許該訪問者訪問它的元素嫩絮;可以是一個復(fù)合(組合模式)或是一個集合,如一個列表或一個無序集合昂羡。
UML
例子
假設(shè)果園里面 有兩個種類的水果樹絮记,蘋果樹和橘子樹!
農(nóng)民和機(jī)器分別要對樹澆水虐先。
抽象一下
訪問者角色:需要澆水
具體訪問者角色; 農(nóng)民 怨愤、機(jī)器
具體元素角色:橘子樹、蘋果樹
對象結(jié)構(gòu)元素蛹批,果園
代碼
<pre>
/**
- Created by zxy on 2017/3/30.
*/
public abstract class Tree {
public abstract void accept(Visitor visitor);
public abstract void water();//澆水操作
}
</pre>
蘋果樹
<pre>
package com.zxy.review.designpattern.structuremodel.visitors;
/**
-
Created by zxy on 2017/3/30.
*/
public class AppleTree extends Tree {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}@Override
public void water() {
System.err.println("I am apple tree,visitor water !");
}
}
</pre>
<pre>
package com.zxy.review.designpattern.structuremodel.visitors;
/**
-
Created by zxy on 2017/3/30.
*/
public class OrangeTree extends Tree {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}@Override
public void water() {
System.err.println("I am Orange tree ,visitor water !");
}
}
</pre>
<pre>
package com.zxy.review.designpattern.structuremodel.visitors;
/**
Created by zxy on 2017/3/30.
-
機(jī)器澆水
*/
public class MachineVisitor implements Visitor{@Override
public void visit(AppleTree appleTree) {
System.out.println("MachineVisitor");
appleTree.water();//接收澆水
}@Override
public void visit(OrangeTree orangeTree) {
System.out.println("MachineVisitor");
orangeTree.water();//接收澆水
}
}
</pre>
<pre>
package com.zxy.review.designpattern.structuremodel.visitors;
/**
- Created by zxy on 2017/3/30.
- 農(nóng)夫澆水
*/
public class FarmerVisitor implements Visitor {
@Override
public void visit(AppleTree appleTree) {
System.out.println("FarmerVisitor");
appleTree.water();//接收澆水
}
@Override
public void visit(OrangeTree orangeTree) {
System.out.println("FarmerVisitor");
orangeTree.water();//接收澆水
}
}
</pre>
果園和調(diào)用類
<pre>
package com.zxy.review.designpattern.structuremodel.visitors;
import java.util.ArrayList;
public class Main {
public static class ManyTrees {
public static ArrayList<Tree> getAllTrees() {
ArrayList<Tree> tree = new ArrayList<>();
for(int i=0;i<3;i++ ){
if(i>1){
tree.add(new AppleTree());
} else {
tree.add(new OrangeTree());
}
}
return tree;
}
}
public static void main(String[] args) {
System.out.println("Hello World!");
ArrayList<Tree> trees = ManyTrees.getAllTrees();
FarmerVisitor farmerVisitor = new FarmerVisitor();
MachineVisitor machineVisitor = new MachineVisitor();
for(int i=0;i< trees.size();i++ ){
trees.get(i).accept(farmerVisitor);
trees.get(i).accept(machineVisitor);
}
}
}
</pre>
結(jié)果