iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Software Development

深入淺出設計模式 - 使用 C++系列 第 28

[Day 28] 不修改對象並為其添加操作 - 訪問者模式 (Visitor Pattern)

  • 分享至 

  • xImage
  •  

(待改進... 終於快結束了 (累...)

Intro

  • Visitor 設計模式是一種行為設計模式,允許您在不修改對象的情況下為其添加更多操作。當您需要處理由不同類型對象組成的結構,並希望對這些對象執行依賴於它們具體類別的操作時,這一模式特別有用

應用

  • 將算法與其操作的對象分離
  • 在不修改現有對象結構的情況下添加新操作

組成

  • Visitor (訪問者): 宣告一個用於對象結構中每種類型的具體元素的 visit 方法的接口或抽象類
  • ConcreteVisitor (具體訪問者): 實現 Visitor,並定義要在每種類型的元素上執行的操作
  • Element (元素): 宣告一個 accept 方法的接口或抽象類
  • ConcreteElement (具體元素): 實現 Element,並定義 accept 方法,該方法通常會調用訪問者的 visit 方法

操作

接受(Acceptance): 每個元素都接受一個訪問者
訪問(Visitation): 訪問者對元素執行一個操作

優點

  • 關注點分離: 它將算法與對象結構分離
  • 開放/封閉原則: 它允許您在不修改現有代碼的情況下添加新操作
  • 單一職責: 每個訪問者實現都處理其自己的一組操作,遵循單一職責原則

缺點

  • 侵入性: 每個元素都必須實現一個 accept 方法
  • 類型安全: 該模式依賴於下轉型 (Down-casting),這可能會容易出錯
  • 可維護性: 添加新類型的元素需要更改 Visitor 接口及其所有實現

使用場景

  • 當您需要對異質結構中的對象執行多個不同且無關的操作時
  • 當您希望通過在一個類中定義它們來保持相關操作在一起時
  • 當對象結構很少更改,但您經常希望定義新操作時

範例

// Element 接口
class Element {
public:
    virtual void accept(class Visitor &v) = 0;
};

// ConcreteElementA
class ConcreteElementA : public Element {
public:
    void accept(Visitor &v) override {
        v.visit(*this);
    }
    
    void operationA() {
        std::cout << "Operation A" << std::endl;
    }
};

// ConcreteElementB
class ConcreteElementB : public Element {
public:
    void accept(Visitor &v) override {
        v.visit(*this);
    }
    
    void operationB() {
        std::cout << "Operation B" << std::endl;
    }
};

// Visitor 接口
class Visitor {
public:
    virtual void visit(ConcreteElementA &element) = 0;
    virtual void visit(ConcreteElementB &element) = 0;
};

// ConcreteVisitor
class ConcreteVisitor : public Visitor {
public:
    void visit(ConcreteElementA &element) override {
        element.operationA();
    }
    void visit(ConcreteElementB &element) override {
        element.operationB();
    }
};


// 主函数
int main() {
    ConcreteElementA elementA;
    ConcreteElementB elementB;
    ConcreteVisitor visitor;

    elementA.accept(visitor);
    elementB.accept(visitor);
}

結論

Visitor 設計模式是一個強大的工具,用於將算法與其操作的對象分離,從而遵循關鍵的軟件設計原則。然而,其應用應謹慎考慮,尤其是在對象結構經常更改的系統中

Reference

  1. ChatGPT 4.0 + Me

上一篇
[Day 27] 複製複雜已知物件 - 原型模式 (Protorype Pattern)
下一篇
《軟體工程篇 - 1》 — 軟體工程與設計模式
系列文
深入淺出設計模式 - 使用 C++37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言