首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 設計模式深度解析:訪問者模式完整實作指南

     編輯:關於C#

前言

在軟體開發中,當我們需要對一個複雜的物件結構執行各種操作,且這些操作會頻繁變動或新增時,若直接在物件類別中添加方法,會違反「開閉原則」並導致類別膨脹。訪問者模式提供了一種優雅的解決方案:將操作從物件結構中分離出來,封裝在獨立的訪問者類別中,使我們能在不修改現有類別的前提下定義新的操作。

核心概念與適用場景

訪問者模式屬於行為型模式,其核心在於「雙重分派」機制。當我們擁有一個相對穩定的物件結構(如文件樹、編譯器的抽象語法樹、GUI 元件樹),但需要對其執行多種且經常變化的操作(如匯出、列印、型別檢查、優化)時,此模式最為適合。它讓演算法與資料結構分離,新增操作只需新增訪問者類別,無需動到元素類別。

類別結構圖解

本範例展示一個訊息處理系統,包含 SQL 和 XML 兩種儲存方式。結構包含以下關鍵角色:

  • Element(抽象元素):定義 Accept(Visitor) 方法,所有具體元素需實作。
  • ConcreteElement(具體元素):SqlMessage、XmlMessage,實作 Accept 並呼叫訪問者的 Visit(this)。
  • Visitor(抽象訪問者):宣告對每種具體元素的 Visit 方法。
  • ConcreteVisitor(具體訪問者):InsertVisitor、GetVisitor,封裝具體操作邏輯。
  • ObjectStructure(物件結構):Messages 集合,負責遍歷元素並接受訪問者。
訪問者模式類別圖

核心程式碼實作

1. 實體模型與抽象基礎

MessageModel 為資料承載類別,包含訊息內容與發布時間。AbstractElement 定義 Accept(AbstractVisitor) 抽象方法,強制子類別實作雙重分派入口。

2. 具體元素:SqlMessage 與 XmlMessage

兩者繼承自 Message(繼承 AbstractElement),各自實作 Get() 與 Insert() 具體邏輯。關鍵在於 Accept 方法:

public override string Accept(AbstractVisitor abstractVisitor)
{
    return abstractVisitor.Visit(this);
}

這行程式碼實現了「雙重分派」:第一次分派由客戶端呼叫 element.Accept(visitor),第二次分派在元素內部呼叫 visitor.Visit(this),讓訪問者得知具體元素型別。

3. 訪問者介面與實作

AbstractVisitor 宣告 Visit(AbstractElement)。具體訪問者 InsertVisitor 與 GetVisitor 分別封裝插入與查詢邏輯,透過型別轉換取得具體元素並呼叫對應方法:

public override string Visit(AbstractElement abstractElement)
{
    Message m = abstractElement as Message;
    return m.Insert().ToString() + "<br />";
}

4. 物件結構與客戶端測試

Messages 類別維護元素集合,提供 Attach/Detach 管理元素,Accept 方法遍歷集合並彙總各元素接受訪問者的結果。客戶端程式碼展示如何組合使用:

Messages m = new Messages();
m.Attach(new SqlMessage(new MessageModel("插入", DateTime.Now)));
m.Attach(new XmlMessage(new MessageModel("插入", DateTime.Now)));

Response.Write(m.Accept(new InsertVisitor()));
Response.Write(m.Accept(new GetVisitor()));

執行結果與分析

程式輸出顯示兩種儲存方式的插入與查詢操作均成功執行:

True
True
SQL方式獲取Message 2007-5-27 15:01:53
XML方式獲取Message 2007-5-27 15:01:53

這證明訪問者模式成功將操作邏輯從元素類別中剝離,新增操作(如 DeleteVisitor)只需新增訪問者類別,完全不需修改 SqlMessage、XmlMessage 或 Messages。

優缺點與最佳實務

優點

  • 符合單一職責原則:操作邏輯集中在訪問者中。
  • 符合開閉原則:新增操作無需修改元素類別。
  • 可跨越多個類別階層操作不同型別物件。
  • 便於在遍歷結構時累積狀態(如計算總價、產生報表)。

缺點

  • 新增元素類別困難:需修改所有訪問者介面與實作(違反開閉原則)。
  • 破壞封裝:訪問者可能需存取元素內部狀態。
  • 適用於「元素結構穩定、操作頻繁變化」的場景;若元素頻繁新增,不宜使用。

總結

訪問者模式透過雙重分派機制,將資料結構與操作演算法解耦,是處理複雜物件結構多樣化操作的利器。本範例以訊息儲存系統為例,完整展示了從抽象定義到具體實作、客戶端使用的全流程。實務上常見於編譯器 AST 遍歷、文件匯出、UI 元件樹操作等領域。掌握此模式,能讓你在面對「演算法變化多於資料結構」的系統時,擁有更靈活、可維護的架構設計能力。


參考資源:DoFactory Visitor Pattern

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved