簡介
訪問者設計模式(Visitor Design Pattern)的定義是,允許一個或多個操作應用到一組物件上,解耦操作和物件本身,
在使用訪問者模式的時候,被訪問的元素通常不是單獨存在的,它們存盤在一個集合中,這個集合稱為“物件結構”,訪問者通過遍歷物件結構實作對其存盤的元素進行逐個訪問,
訪問者模式使用了“雙重分派”的呼叫機制,即元素物件定義一個操作方法支持注入訪問者物件,在操作方法內呼叫訪問者的訪問方法,并將當前元素物件傳入到訪問方法中,
具體實作
在這里舉一個作業當中的具體例子,在小公司的專案組當中,名義上區分了開發、測驗等崗位,但實際上開發人員既要會開發,也有會測驗,對于測驗人員也是同樣的要求,既要會測驗,也要會開發,
在這里案例當中,開發人員、測驗人員統稱為元素,我們在這里先構建一個抽象的元素類,其代碼示例如下:
public interface Element {
// 定義一個接受訪問者訪問的抽象方法
void accept(Visitor visitor);
}
對于開發人員類,根據自己的情況實作這個 accept() 方法,其代碼如下:
public class Programmer implements Element {
private String name = "開發人員";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
visitor.visitProgrammer(this);
}
}
對于測驗人員,根據自己的情況實作這個 accept() 方法,其代碼如下:
public class Tester implements Element {
private String name = "測驗人員";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
visitor.visitTester(this);
}
}
第二步,最重要的就是要定義好一個訪問者類,在這里抽象出的訪問者介面可以是以專案組為范圍,為專案組中的每一個元素定義對應的訪問方法,其代碼示例如下:
public interface Visitor {
void visitProgrammer(Programmer programmer);
void visitTester(Tester tester);
}
每當出現一個新的操作時,就可以實作訪問者介面,注入不同的元素物件以實作不同的操作,
如下是開發人員和測驗人員使用開發技能的代碼示例:
public class DevelopVisitor implements Visitor {
@Override
public void visitProgrammer(Programmer programmer) {
System.out.println(programmer.getName() + "在開發");
}
@Override
public void visitTester(Tester tester) {
System.out.println(tester.getName() + "在開發");
}
}
如下是開發人員和測驗人員使用測驗技能的代碼示例:
public class TestVisitor implements Visitor {
@Override
public void visitProgrammer(Programmer programmer) {
System.out.println(programmer.getName() + "在測驗");
}
@Override
public void visitTester(Tester tester) {
System.out.println(tester.getName() + "在測驗");
}
}
總結
優點
訪問者模式的主要優點如下:
- 能夠在不修改物件結構中的元素的情況下,為物件結構中的元素添加新的功能,符合開閉原則
- 將有關元素的行為都封裝到一個訪問者物件中,每個訪問者物件的功能都比較單一,符合單一職責原則
缺點
訪問者模式的主要缺點如下:
- 增加新的元素類需要在每一個訪問者類中都增加相應的具體操作,這違背了開閉原則
- 訪問者物件可以訪問并呼叫每一個元素物件的操作,這意味著元素物件有時候會暴露一些內部操作和內部狀態,破壞了封裝
- 訪問者模式依賴了具體類,而沒有依賴抽象類,違反了依賴倒置原則
適用場景
訪問者模式的適用場景如下:
- 物件結構中元素物件的類很少改變,但經常需要在此物件結構上定義新的操作
原始碼
訪問者模式提供一個方便的可維護的方式來操作一組物件,JDK 內置了這樣的元素介面和訪問者介面,
如下是元素介面 javax.lang.model.element.Element 的部分代碼:
public interface Element extends javax.lang.model.AnnotatedConstruct {
<R, P> R accept(ElementVisitor<R, P> v, P p);
}
如下是訪問者介面 javax.lang.model.element.ElementVisitor 的部分代碼:
public interface ElementVisitor<R, P> {
R visit(Element e, P p);
default R visit(Element e) {
return visit(e, null);
}
}
首發于翔仔的個人博客,點擊查看更多,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/531529.html
標籤:其他
