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

C# 設計模式:訪問者模式完整指南(二)— 結構性代碼與雙重分派機制詳解

     編輯:關於C語言

結構性示範代碼


using System;
using System.Collections;

// 抽象訪問者:針對每種具體元素宣告訪問方法
abstract class Visitor
{
    public abstract void VisitConcreteElementA(ConcreteElementA e);
    public abstract void VisitConcreteElementB(ConcreteElementB e);
}

// 具體訪問者 1
class ConcreteVisitor1 : Visitor
{
    public override void VisitConcreteElementA(ConcreteElementA e)
        => Console.WriteLine($"{e} visited by {this}");

    public override void VisitConcreteElementB(ConcreteElementB e)
        => Console.WriteLine($"{e} visited by {this}");
}

// 具體訪問者 2
class ConcreteVisitor2 : Visitor
{
    public override void VisitConcreteElementA(ConcreteElementA e)
        => Console.WriteLine($"{e} visited by {this}");

    public override void VisitConcreteElementB(ConcreteElementB e)
        => Console.WriteLine($"{e} visited by {this}");
}

// 抽象元素
abstract class Element
{
    public abstract void Accept(Visitor visitor);
}

// 具體元素 A
class ConcreteElementA : Element
{
    public override void Accept(Visitor visitor) => visitor.VisitConcreteElementA(this);
    public void OperationA() { }
}

// 具體元素 B
class ConcreteElementB : Element
{
    public override void Accept(Visitor visitor) => visitor.VisitConcreteElementB(this);
    public void OperationB() { }
}

// 物件結構
class ObjectStructure
{
    private ArrayList elements = new ArrayList();
    public void Attach(Element e) => elements.Add(e);
    public void Detach(Element e) => elements.Remove(e);
    public void Accept(Visitor visitor)
    {
        foreach (Element e in elements) e.Accept(visitor);
    }
}

// 客戶端
public class Client
{
    public static void Main()
    {
        ObjectStructure os = new ObjectStructure();
        os.Attach(new ConcreteElementA());
        os.Attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        os.Accept(v1);
        os.Accept(v2);
    }
}

雙重分派過程詳細拆解

以 ConcreteElementA 接受 ConcreteVisitor1 為例:

  1. ConcreteElementA.Accept(v1) 被調用,傳入 v1
  2. ConcreteElementA 反向調用 v1.VisitConcreteElementA(this),傳入自己
  3. v1 執行 ConcreteElementA.OperationA() 等業務邏輯

**關鍵點**:元素主動將自己傳給訪問者,訪問者再根據元素具體類型調用對應方法——這就是「雙重分派」。

系統層面的雙重分派

  • ObjectStructure 遍歷所有元素
  • 每個元素觸發一次雙重分派
  • 系統有 N 個節點 = 發生 N 次雙重分派
  • 遍歷過程 = 對所有節點委派的過程 = 雙重分派的集合

角色對應表

角色類別職責
抽象訪問者Visitor宣告所有具體元素的訪問介面
具體訪問者ConcreteVisitor1/2實作各元素的具體訪問邏輯
抽象元素Element宣告 Accept(Visitor) 介面
具體元素ConcreteElementA/B實作 Accept,反向調用訪問者對應方法
物件結構ObjectStructure管理元素集合,提供遍歷接受訪問者
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved