Visitor Pattern(訪問者模式)

訪問者模式(Visitor Pattern)訪問者模式是一種將數(shù)據(jù)操作和數(shù)據(jù)結構分離的設計模式。這種類型的設計模式屬于行為型模式。根據(jù)模式,元素對象已接受訪問者對象,這樣訪問者對象就可以處理元素對象上的操作。

介紹

  • 意圖:主要將數(shù)據(jù)結構與數(shù)據(jù)操作分離。
  • 主要解決:穩(wěn)定的數(shù)據(jù)結構和易變的操作耦合問題。
  • 何時使用:需要對一個對象結構中的對象進行很多不同的并且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,使用訪問者模式將這些封裝到類中。
  • 如何解決:在被訪問的類里面加一個對外提供接待訪問者的接口。
  • 關鍵代碼:在數(shù)據(jù)基礎類里面有一個方法接受訪問者,將自身引用傳入訪問者。
  • 優(yōu)點:
    1、符合單一職責原則。
    2、優(yōu)秀的擴展性。
    3、靈活性。
  • 缺點:
    1、具體元素對訪問者公布細節(jié),違反了迪米特原則。
    2、具體元素變更比較困難。
    3、違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
  • 使用場景:
    1、對象結構中對象對應的類很少改變,但經(jīng)常需要在此對象結構上定義新的操作。
    2、需要對一個對象結構中的對象進行很多不同的并且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,也不希望在增加新操作時修改這些類。

注意事項:訪問者可以對功能進行統(tǒng)一,可以做報表、UI、攔截器與過濾器。

示例

ComputerPart.ts 表示元素的接口
import { ComputerPartVisitor } from "./ComputerPartVisitor";

export interface ComputerPart {
    accept(computerPartVisitor: ComputerPartVisitor): void;
}
Keyboard.ts 鍵盤實體類
import { ComputerPartVisitor } from "./ComputerPartVisitor";
import { ComputerPart } from "./ComputerPart";

export default class Keyboard implements ComputerPart {
    public name: string;
    public accept(computerPartVisitor: ComputerPartVisitor): void {
        this.name = "Keyboard";
        computerPartVisitor.visit(this);
    }
}
Mouse.ts 鼠標實體類
import { ComputerPartVisitor } from "./ComputerPartVisitor";
import { ComputerPart } from "./ComputerPart";

export default class Mouse implements ComputerPart {
    public name: string;
    public accept(computerPartVisitor: ComputerPartVisitor): void {
        this.name = "Mouse";
        computerPartVisitor.visit(this);
    }
}
Monitor.ts 顯示器實體類
import { ComputerPartVisitor } from "./ComputerPartVisitor";
import { ComputerPart } from "./ComputerPart";

export default class Monitor implements ComputerPart {
    public name: string;
    public accept(computerPartVisitor: ComputerPartVisitor): void {
        this.name = "Monitor";
        computerPartVisitor.visit(this);
    }
}
Computer.ts 計算機實體類
import { ComputerPartVisitor } from "./ComputerPartVisitor";
import Mouse from "./Mouse";
import Keyboard from "./Keyboard";
import Monitor from "./Monitor";
import { ComputerPart } from "./ComputerPart";

export default class Computer implements ComputerPart {

    private parts: ComputerPart[];
    public name: string;
    constructor() {
        this.parts = [new Mouse(), new Keyboard(), new Monitor()];
        this.name = "Computer";
    }


    public accept(computerPartVisitor: ComputerPartVisitor): void {
        for (let i = 0; i < this.parts.length; i++) {
            this.parts[i].accept(computerPartVisitor);
        }
        computerPartVisitor.visit(this);
    }
}
ComputerPartVisitor.ts 訪問者的接口
import Computer from "./Computer";
import Mouse from "./Mouse";
import Keyboard from "./Keyboard";
import Monitor from "./Monitor";

export interface ComputerPartVisitor {
    visit(obj: Computer | Mouse | Keyboard | Monitor): void;
}
ComputerPartDisplayVisitor.ts 創(chuàng)建實現(xiàn)了上述類的實體訪問者。
import { ComputerPartVisitor } from "./ComputerPartVisitor";
import Computer from "./Computer";
import Mouse from "./Mouse";
import Keyboard from "./Keyboard";
import Monitor from "./Monitor";

export default class ComputerPartDisplayVisitor implements ComputerPartVisitor {
    public visit(obj: Computer | Mouse | Keyboard | Monitor): void {//JavaScript中沒有重載
        console.log(obj.name)
        if (obj.name === "Computer") {
            console.log("Displaying Computer.");

        } else if (obj.name === "Mouse") {

            console.log("Displaying Mouse.");
        } else if (obj.name === "Keyboard") {

            console.log("Displaying Keyboard.");
        } else {
            console.log("Displaying Monitor.");

        }
    }
}
index.ts
import { ComputerPart } from "./ComputerPart";
import Computer from "./Computer";
import ComputerPartDisplayVisitor from "./ComputerPartDisplayVisitor";

const computer: ComputerPart = new Computer();
computer.accept(new ComputerPartDisplayVisitor());
result
Mouse
Displaying Mouse.
Keyboard
Displaying Keyboard.
Monitor
Displaying Monitor.
Computer
Displaying Computer.

類圖

角色

  • Visitor(訪問者)
    Visitor角色負責對數(shù)據(jù)結構中每個具體的元素聲明一個訪問的visit方法,visit方法是用來操作元素的方法,負責實現(xiàn)該方法的是concreteVisitor角色
  • ConcreteVisitor(具體的訪問者)
    ConcreteVisitor角色負責實現(xiàn)Visitor角色定影的接口,它要實現(xiàn)所有的visit方法,即實現(xiàn)如何處理每個ConcreteElement角色。ConcreteVisitor角色的內部狀態(tài)會隨著visit的變化而變化
  • Element(元素)
    Element角色表示Visitor角色的訪問對象。它聲明了接受訪問者的accept方法。accept方法接受的參數(shù)是Visitor角色。
  • ConcreteElement
    ConcreteElement負責實現(xiàn)Element角色定義的接口
  • ObjectStructure(對象結構)
    ObjectStructure角色負責吃力Element角色的集合。ConcreteVisitor角色為每個Element都準備了處理方法。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容