GoF對訪問者模式定義爲:表示一個作用於某對象結構中各元素的操作。它可以使你不修改各元素類的前提下定義作用於這些元素的新操作,也就是動態的增加新的方法。
Visitor模式是一種分離對象數據結構與行爲的方法,通過這種分離,可以爲一個已存在的類或類羣增加新的操作而無需爲它們作任何修改。
Visitor模式的優點:
- 分離對象的數據結構與行爲,讓不同的類完成不同的功能
- 可以不修改已有類的基礎上增加新的操作行爲
- 從另一個角度來看,同一個數據結構,爲其實現不同的觀察者,便可呈現不同的行爲
該模式結構如下:
Visitor模式的實現步驟:
1,定義具有繼承關係的數據結構對象羣(相當於Element與ConcreteElement角色),並定義accept(Visitor)方法接受Visitor訪問
2,定義包含上述數據結構對象羣的複合結構對象(相當於ObjectStructure角色)
3,定義Visitor抽象接口,定義所有訪問行爲方法(相當於Visitor角色)
4,定義具體的訪問者對象,並實現所有visit方法(相當於ConcreteVisitor角色)
舉個例子:
一個公司(corporation)有幾個不同的部門,A管理A部(PartA),B管理B部(PartB),CEO兩者都管。
代碼實現如下:
import java.util.ArrayList;
import java.util.List;
//訪問者
interface Visitor {
public void visit(PartA A);
public void visit(PartB B);
}
class A implements Visitor {
@Override
public void visit(PartA A) {
// TODO Auto-generated method stub
System.out.println("A 主管" + A.getName());
}
@Override
public void visit(PartB B) {
// TODO Auto-generated method stub
}
}
class B implements Visitor {
@Override
public void visit(PartA A) {
// TODO Auto-generated method stub
}
@Override
public void visit(PartB B) {
// TODO Auto-generated method stub
System.out.println("B 主管" + B.getName());
}
}
class CEO implements Visitor {
@Override
public void visit(PartA A) {
// TODO Auto-generated method stub
System.out.println("CEO主管" + A.getName());
}
@Override
public void visit(PartB B) {
// TODO Auto-generated method stub
System.out.println("CEO主管" + B.getName());
}
}
//被訪問結點
interface Corporation {
public void accapt(Visitor v);
}
class PartA implements Corporation{
String s = "PartA";
@Override
public void accapt(Visitor v) {
// TODO Auto-generated method stub
v.visit(this);
}
public String getName() {
// TODO Auto-generated method stub
return s;
}
}
class PartB implements Corporation {
String s = "PartB";
@Override
public void accapt(Visitor v) {
// TODO Auto-generated method stub
v.visit(this);
}
public String getName() {
// TODO Auto-generated method stub
return s;
}
}
//提供一個高層接口以允許該訪問者訪問它的元素
class ObjectStructure {
public List<Corporation> eumn = new ArrayList<Corporation>();
public void addVisitor(Corporation e){
eumn.add(e);
}
public void removeVisitor(Corporation e){
eumn.remove(e);
}
public void accapt(Visitor v){
for(Corporation e:eumn)
e.accapt(v);
}
}
//測試類
public class Test {
public static void main(String[] args) {
Visitor ceo = new CEO();
Visitor a = new A();
Visitor b = new B();
Corporation pa = new PartA();
Corporation pb = new PartB();
ObjectStructure os = new ObjectStructure();
os.addVisitor(pa);
os.addVisitor(pb);
os.accapt(ceo);
os.accapt(a);
os.accapt(b);
}
}
輸出結果:
CEO主管PartA
CEO主管PartB
A 主管PartA
B 主管PartB