C++ 設計模式之訪問者模式

C++ 設計模式之訪問者模式

簡介

1、訪問者模式 (Visitor)是一種行為型設計模式,它表示一個作用于某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。 使用該模式可以在不修改已有程序結構的前提下,通過添加額外的訪問者類實現新的操作。

2、訪問者模式 (Visitor)應用場景包括但不限于:
2.1、對象結構比較穩定,但操作經常變化的程序。
2.2、需要對一個對象結構中的對象進行很多不同而且不相關的操作,而你想避免讓這些操作“污染”這些對象的類。

3、訪問者模式 (Visitor)的構成
3.1、訪問者(Visitor):定義了一個訪問操作中的元素的接口。這個接口使得訪問者可以不修改類的結構就可以增加新的操作。

class DocumentVisitor
{
public:virtual ~DocumentVisitor() {}virtual void visitParagraph(class ParagraphElement* element) = 0;virtual void visitImage(class ImageElement* element) = 0;virtual void visitTable(class TableElement* element) = 0;
};

3.2、元素(Element):聲明一個接受訪問者對象的接口。這個接口通常包含一個或多個由訪問者接口定義的方法。

class DocumentElement
{
public:virtual ~DocumentElement() {}virtual void accept(DocumentVisitor* visitor) = 0;
};

4、訪問者模式 (Visitor)的優點
4.1、封裝性: 可以在不改變元素類的情況下定義新的操作。
4.2、擴展性: 新的訪問者可以很容易地添加新的操作。
4.3、分離關注點: 移動相關的操作集中到訪問者中,而不是分散在元素類中。

5、訪問者模式 (Visitor)的缺點
5.1、違反封裝: 訪問者可能需要訪問元素的內部細節,這通常意味著元素必須暴露一些原本應該是私有的數據。
5.2、復雜度: 可以使系統變得更加復雜,特別是當系統有大量元素時。
5.3、對象結構變化困難: 如果經常改變對象結構的元素類,那么維護訪問者模式將會非常麻煩。

簡單示例

1、定義

// 抽象訪問者
class DocumentVisitor
{
public:virtual ~DocumentVisitor() {}virtual void visitParagraph(class ParagraphElement* element) = 0;virtual void visitImage(class ImageElement* element) = 0;virtual void visitTable(class TableElement* element) = 0;
};// 元素基類
class DocumentElement
{
public:virtual ~DocumentElement() {}virtual void accept(DocumentVisitor* visitor) = 0;
};class ParagraphElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};class ImageElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};class TableElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};// 渲染訪問者
class RenderVisitor : public DocumentVisitor
{
public:void visitParagraph(class ParagraphElement* element);void visitImage(class ImageElement* element);void visitTable(class TableElement* element);
};// 檢查訪問者  
class CheckVisitor : public DocumentVisitor
{
public:void visitParagraph(class ParagraphElement* element);void visitImage(class ImageElement* element);void visitTable(class TableElement* element);
};

2、實現

void ParagraphElement::accept(DocumentVisitor* visitor)
{visitor->visitParagraph(this);
}void ImageElement::accept(DocumentVisitor* visitor)
{visitor->visitImage(this);
}void TableElement::accept(DocumentVisitor* visitor)
{visitor->visitTable(this);
}void RenderVisitor::visitParagraph(class ParagraphElement* element)
{std::cout << "Render Paragraph" << std::endl;
}void RenderVisitor::visitImage(class ImageElement* element)
{std::cout << "Render Image" << std::endl;
}void RenderVisitor::visitTable(class TableElement* element)
{std::cout << "Render Table" << std::endl;
}void CheckVisitor::visitParagraph(class ParagraphElement* element)
{std::cout << "Check Paragraph" << std::endl;
}void CheckVisitor::visitImage(class ImageElement* element)
{std::cout << "Check Image" << std::endl;
}void CheckVisitor::visitTable(class TableElement* element)
{std::cout << "Check Table" << std::endl;
}

3、調用

std::vector<DocumentElement*> vecDoc = {new ParagraphElement(),new ImageElement(),new TableElement()
};
RenderVisitor renderVisitor;
CheckVisitor checkVisitor;for (auto elem : vecDoc)
{elem->accept(&renderVisitor);elem->accept(&checkVisitor);
}for (auto el : vecDoc)
{delete el;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37080.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue3 全局引入 onMounted, reactive, ref 的插件全局引入

webpack 的引入 npm install -D unplugin-auto-import const AutoImport require(unplugin-auto-import/webpack).default;configureWebpack: {devtool: source-map,module: {rules: [{test: /\.mjs$/,include: /node_modules/,type: javascript/auto}],}, plugins: [Aut…

Java對象創建過程

在日常開發中&#xff0c;我們常常需要創建對象&#xff0c;那么通過new關鍵字創建對象的執行中涉及到哪些流程呢&#xff1f;本文主要圍繞這個問題來展開。 類的加載 創建對象時我們常常使用new關鍵字。如下 ObjectA o new ObjectA();對虛擬機來講首先需要判斷ObjectA類的…

Java代碼質量管理與持續集成

Java代碼質量管理與持續集成 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 引言 在當今軟件開發的環境中&#xff0c;高質量的代碼和持續集成是保證軟件項目…

# Sharding-JDBC從入門到精通(4)- Sharding-JDBC 入門程序幾種配置方式

Sharding-JDBC從入門到精通&#xff08;4&#xff09;- Sharding-JDBC 入門程序幾種配置方式 一、Sharding-JDBC 入門程序&#xff08;水平分表&#xff09;-使用 application.yml 配置文件的 方式 1、打開 idea 創建 artifactId 名為 dbsharding 的 maven 父工程。 --> i…

python sklearn機械學習模型-回歸

&#x1f308;所屬專欄&#xff1a;【機械學習】?作者主頁&#xff1a; Mr.Zwq??個人簡介&#xff1a;一個正在努力學技術的Python領域創作者&#xff0c;擅長爬蟲&#xff0c;逆向&#xff0c;全棧方向&#xff0c;專注基礎和實戰分享&#xff0c;歡迎咨詢&#xff01; 您…

redis實戰-添加商戶緩存

為什么要使用緩存 言簡意賅&#xff1a;速度快&#xff0c;好用緩存數據存儲于代碼中&#xff0c;而代碼運行在內存中&#xff0c;內存的讀寫性能遠高于磁盤&#xff0c;緩存可以大大降低用戶訪問并發量帶來的服務器讀寫壓力實際開發中&#xff0c;企業的數據量&#xff0c;少…

找不到mfc100.dll文件怎么辦?推薦這7個解決方法快速解決mfc100.dll丟失問題

使用電腦中&#xff0c;會遇到各種各樣的問題&#xff0c;比如找不到mfc100.dll&#xff0c;或mfc100.dll丟失導致軟件程序無法繼續運行&#xff0c;就是日常中比較常見的問題之一&#xff0c;今天我教大家遇到這個mfc100.dll丟失問題時候&#xff0c;要怎么解決&#xff0c;以…

【List集合排序】

List集合排序Demo import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor;import java.util.*;/*** list order demo*/ public class ListOrderDemo {public static void main(String[] args) {List<String> lis…

以太網幀格式是如何識別有效負載類型的

注&#xff1a;機翻&#xff0c;未校對。 識別以太網幀有效負載 Identifying Ethernet Frame Payloads Ethernet frames contain payload data encapsulated within header and trailer fields used to deliver packets over Layer 2 networks. This article provides an ov…

套接字通信類的封裝

在掌握了基于TCP的套接字通信流程之后&#xff0c;為了方便使用&#xff0c;提高編碼效率&#xff0c;可以對通信操作進行封裝&#xff0c;本著有淺入深的原則&#xff0c;先基于C語言進行面向過程的函數封裝&#xff0c;然后再基于C進行面向對象的類封裝。 1. 基于C語言的封裝…

Linux基礎篇——學習Linux基本工具安裝教程視頻鏈接

本篇文章就是記錄一下學習Linux需要用到的基本工具的視頻教程鏈接&#xff0c;方便以后查看 VMware15.5安裝 安裝視頻教程&#xff1a;VMware15.5安裝教程 centos7.6安裝&#xff08;這個視頻教程真的很nice&#xff09; 視頻教程&#xff1a;centos7.6 虛擬機克隆、快照、…

ansible 模塊擴展

uri模塊 在Ansible中&#xff0c;uri模塊是一個用于發送HTTP、HTTPS、FTP等請求的模塊&#xff0c;可以用于獲取網頁內容、下載文件、上傳文件等。本質上&#xff0c;它是一個HTTP客戶端模塊。 使用uri模塊&#xff0c;需要指定一些參數來定義HTTP請求。下面是一些uri模塊的常…

學習平臺推薦_菜鳥教程官網

網址&#xff1a; 菜鳥教程 - 學的不僅是技術&#xff0c;更是夢想&#xff01;菜鳥教程(www.runoob.com)提供了編程的基礎技術教程, 介紹了HTML、CSS、Javascript、Python&#xff0c;Java&#xff0c;Ruby&#xff0c;C&#xff0c;PHP , MySQL等各種編程語言的基礎知識。 同…

Nginx-2

一、高級配置 1.1網頁狀態頁 基于nginx 模塊 ngx_http_stub_status_module 實現&#xff0c;在編譯安裝nginx的時候需要添加編譯參數 --with-http_stub_status_module&#xff0c;否則配置完成之后監測會是提示語法錯誤注意: 狀態頁顯示的是整個服務器的狀態,而非虛擬主機的狀…

opencv實現surface_matching記錄

1 說明 使用的cv版本為4.7.0 , surface_matching功能是附加在contrib中的,并未直接包含在opencv 4.7.0中,因此編譯的時候需要考慮contrib。 VS版本為2022, CMake版本為3.30-rc4. 2 編譯opencv(含contrib) 參見: Win10 下編譯 OpenCV 4.7.0詳細全過程,包含xfeatures2…

Open3D (C++) 點云邊界提取

邊界提取 一、算法原理1、詳細流程2、主要函數3、參考文獻二、代碼實現三、結果展示四、注意事項本文由CSDN點云俠原創,原文鏈接。如果你不是在點云俠的博客中看到該文章,那么此處便是不要臉的爬蟲。 一、算法原理 1、詳細流程 該算法完全復刻自PCL。 2、主要函數 /// \…

算法入門(上)

什么是算法&#xff1f; 算法&#xff08;Algorithm&#xff09;是解決特定問題求解步驟的描述&#xff0c;在計算機中表現為指令的有限序列&#xff0c;并且每條指令表示一個或多個操作。 給定一個問題&#xff0c;能夠解決這個問題的算法是有很多種的。算式中的問題是千奇百怪…

C++為什么將 0.1f 更改為 0 性能會降低 10 倍

一、浮點數與整數的表示差異 在計算機內部&#xff0c;浮點數和整數的表示方式截然不同。浮點數遵循IEEE 754標準&#xff0c;通過符號位、指數位和尾數位來存儲和表示數值&#xff0c;而整數則是直接的二進制表示。這種表示上的差異導致了它們在內存占用、處理速度以及精度上…

Debian/Ubuntu Linux安裝OBS

先決條件 建議使用 xserver-xorg 1.18.4 或更新版本&#xff0c;以避免 OBS 中某些功能&#xff08;例如全屏投影儀&#xff09;出現潛在的性能問題。在 Linux 上使用 OBS Studio 需要 OpenGL 3.3&#xff08;或更高版本&#xff09;支持。在終端中輸入以下內容來檢查系統支持…

Halcon測量助手

模糊測量:基于模糊邏輯 模糊邏輯&#xff1a;模仿人腦的不確定性概念判斷、推理思維方式&#xff0c;對于模型未知或不能確定的描述系統&#xff0c;以及強非線性、大滯后的控制對象&#xff0c;應用模糊集合和模糊規則進行推理&#xff0c;表達過渡性界限或定性知識經驗&…