設計模式24——訪問者模式

寫文章的初心主要是用來幫助自己快速的回憶這個模式該怎么用,主要是下面的UML圖可以起到大作用,在你學習過一遍以后可能會遺忘,忘記了不要緊,只要看一眼UML圖就能想起來了。同時也請大家多多指教。

訪問者模式(Visitor)

對象行為型模式。

目錄

一、概述

1.1、直觀的理解:

1.2、主要角色:

1.3、描述上述對象之間關系的UML圖:

1.4、適用場景:

二、代碼舉例

2.1、對象之間的關系用UML圖描述如下:

2.2、Java代碼如下:


一、概述

1、表示一個作用于某對象結構中的各個元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作;

2、這算法應當是針對這數據結構里每一個對象建對應的處理,也就是算法對象里有一整個操作集合,使得每一個對象都可以根據不同的具體算法都同一時間段內單獨的操作一下。而針對不同的時間段,又可以新建不同的算法類,同樣算法類里也應該有在同一時間段里對那些數據結構類群里的所有對象的操作。

1.1、直觀的理解

假設有3個元素,且對這些元素有兩種操作需要實現,使用訪問者模式我們邏輯上的思考應該是:

但在代碼實現上,我們還需要再加一個枚舉元素的類,他存儲了所有相關的元素,并且可以枚舉它們,方便訪問者操作那些元素。

就拿訪問者A訪問元素1、2、3為例,活動圖如下:

1.2、主要角色:

  • 訪問者:訪問者的抽象類或接口 + 訪問者類,操作元素的類
  • 元素:元素的抽象類或接口 + 元素類,被操作的對象
  • 枚舉元素類的類(ObjectStructure對象結構):保存著元素類的集合,并且可以遍歷已保存的元素方便訪問者訪問

1.3、描述上述對象之間關系的UML圖:

1.4、適用場景:

  • 一個對象結構包含很多類對象,它們有著不同的接口,而你想對這些對象實施一些依賴于其具體類的操作
  • 需要對一個對象結構中的對象進行很多不太并且不相關的操作,而你想要避免讓這些操作“污染”這些對象的類
  • 適合于數據結構相對穩定的系統。它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化

二、代碼舉例

假設有元素A和B,在它們之上有兩類操作,那么設計出訪問者1和2。這個例子比較簡單,就不再詳細分析了。但你可以把本例當做一個模板,然后靈活使用:

2.1、對象之間的關系用UML圖描述如下:

2.2、Java代碼如下:

訪問者的抽象類:

abstract class Visitor {public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}

元素的抽象類:

abstract class Element {public abstract void accept(Visitor visitor);
}

元素類A:

public class ConcreteElementA extends Element{@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementA(this);}//其他操作
}

元素類B:

public class ConcreteElementB extends Element{@Overridepublic void accept(Visitor visitor) {visitor.visitConcreteElementB(this);}//其他操作
}

訪問者1:

public class ConcreteVisitor1 extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "訪問");}@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "訪問");}
}

訪問者2:

public class ConcreteVisitor2 extends Visitor {@Overridepublic void visitConcreteElementA(ConcreteElementA concreteElementA) {System.out.println(concreteElementA.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "訪問");}@Overridepublic void visitConcreteElementB(ConcreteElementB concreteElementB) {System.out.println(concreteElementB.getClass().getSimpleName() + "被" + this.getClass().getSimpleName() + "訪問");}
}

枚舉元素類的類:

public class ObjectStructure {private List<Element> elements = new ArrayList<>();public void attach(Element element) {elements.add(element);}public void detach(Element element) {elements.remove(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}

主程序(發起請求的類):

public class Main {public static void main(String[] args) {ObjectStructure objectStructure = new ObjectStructure();objectStructure.attach(new ConcreteElementA());objectStructure.attach(new ConcreteElementB());objectStructure.accept(new ConcreteVisitor1());objectStructure.accept(new ConcreteVisitor2());}
}

這里就不再舉例了,可以把上面的Java例子復制到你本地,運行main函數試一下加深理解。這些代碼都是我自己學習的時候根據一些教材手敲的,不存在bug可以直接運行。

如果覺得本文還不錯,就請點個贊給作者一點鼓勵吧!如果有建議,也請評論指教和討論!

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

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

相關文章

cuda編程筆記(2)--傳遞參數、設備屬性

以下是最簡單的帶參數的核函數使用過程&#xff1a; #include<iostream> #include<cstdio> #include "cuda_runtime.h" #include "device_launch_parameters.h" __global__ void add(int a,int b,int *c) {*c a b; } int main() {int c;int…

C# WinForm應用程序多語言實現全面指南

目錄 引言 一、多語言實現基礎概念 1.1 多語言實現的核心原理 1.2 .NET本地化支持機制 二、基于XML的多語言實現方案 2.1 方案概述 2.2 XML文件結構示例 2.3 實現步驟 2.4 優缺點分析 三、基于.resx資源文件的多語言實現 3.1 方案概述 3.2 實現步驟 3.3 資源文件結…

Python爬蟲實戰:研究Playwright框架相關技術

1 引言 1.1 研究背景與意義 網絡爬蟲作為一種自動獲取互聯網信息的技術,在數據采集、信息監測、競爭情報等領域具有廣泛應用。隨著 Web 技術的發展,越來越多的網站采用 JavaScript 動態渲染技術,傳統爬蟲工具難以有效獲取完整的頁面內容。Playwright 作為新一代自動化測試…

中企出海大會|打造全球化云計算一張網,云網絡助力中企出海和AI創新

全球化是阿里云的長期戰略&#xff0c;未來阿里云將持續加大云和 AI 基礎設施建設投入。首先是加速打造全球化的云計算網絡&#xff0c;一張具備 AI技術服務能力和全球競爭力的云計算網絡是阿里云的長期目標。 —— 阿里巴巴集團 CEO、阿里云智能集團董事長兼 CEO 吳泳銘 5 月 …

唯創WT2606B TFT顯示靈動方案,重構電子鎖人機互動界面,賦能智能門鎖全場景交互!

在智能家居的浪潮中&#xff0c;門鎖搭載顯示屏已成為行業創新的焦點。據行業數據顯示&#xff0c;2023年全球智能門鎖出貨量中&#xff0c;搭載顯示屏的型號占比已突破40%&#xff0c;且年復合增長率達25%。而2024年國內智能門鎖銷量突破2200萬套&#xff0c;預計2025年市場規…

輕量化開源方案——淺析PdfPatcher實際應用

PDF處理在實際工作中十分重要&#xff0c;今天淺析PdfPatcher在PDF處理中的實際應用。 核心功能實測 批量處理能力 支持修改文檔屬性/頁碼編號/頁面鏈接 一鍵清除復制/打印限制&#xff08;實測WPS加密文檔可解鎖&#xff09; 自動清理隱藏冗余數據&#xff08;經測試可平均…

Docker 環境搭建與三大數據庫(MySQL/Redis/MongoDB)部署教程

Docker 環境搭建與三大數據庫(MySQL/Redis/MongoDB)部署教程 一、簡介二、安裝wsl三、wsl磁盤遷移四、wsl磁盤壓縮五、Docker下載六、win11配置docker虛擬環境命令工具七、Docker部署mysql八、Docker部署redis九、Docker部署mongo一、簡介 Docker 是一個開源的容器化平臺,它…

CPO-BP+MOPSO,冠豪豬優化BP神經網絡+多目標粒子群算法!(Matlab源碼)

目錄 效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 1.CPO-BPNSGA&#xff0c;冠豪豬優化BP神經網絡粒子群算法&#xff01;&#xff08;Matlab完整源碼和數據&#xff09;&#xff0c;冠豪豬算法優化BP神經網絡的權值和閾值&#xff0c;運行環境Matlab2020b及以上。 多…

Vision Pro發布!開發者如何快速上手空間UI設計?

Vision Pro發布&#xff01;開發者如何快速上手空間UI設計&#xff1f; 【內容摘要】 蘋果最新發布的Vision Pro&#xff0c;不僅重新定義了我們對虛擬現實&#xff08;VR&#xff09;和增強現實&#xff08;AR&#xff09;的認知&#xff0c;也為開發者們帶來了前所未有的機…

Bootstrap法進行隨機模擬

一、問題背景 # 26名神經功能受損兒童接受了兩組&#xff08;A組與B組&#xff09;空間知覺測試&#xff0c;得分如下A組和B組數據。 # A組數據 x_A <- c(48, 36, 20, 29, 42, 42, 20, 42, 22, 41, 45, 14, 6, 0, 33, 28, 34, 4, 32, 24, 47, 41, 24, 26, 30, 41)# B組數據…

Spring AI 多模型智能協作工作流實現指南

Spring AI 多模型智能協作工作流實現指南 說明 本文檔旨在指導開發者基于 Spring AI 框架&#xff0c;在 Spring Boot 2 環境下集成多種主流大語言模型&#xff08;如 OpenAI ChatGPT、Deepseek、阿里云通義千問等&#xff09;&#xff0c;并提供從環境配置、模型調用、流式輸…

C語言中清空緩存區到底寫到哪里比較好

文章目錄 問題背景%d和%c讀取緩沖區的差別清空緩存區 問題背景 在寫C語言的命令行程序時&#xff0c;我們經常會用到用戶輸入和標準輸出&#xff0c;特別的&#xff0c;當用戶輸入后&#xff0c;我們發現程序運行不是我們要的樣子&#xff0c;這個時候&#xff0c;很可能就是輸…

計算機視覺與深度學習 | 基于 YOLOv8 + BeautyGAN + CodeFormer + Face Parsing 實現簡單的人臉美顏

人臉美顏 **一、算法流程圖****二、完整代碼實現**1. 環境準備2. 完整代碼(face_beautify.py)**三、核心算法公式**1. YOLOv8檢測損失函數2. BeautyGAN損失函數3. CodeFormer圖像重建公式**四、關鍵實現細節**1. 多尺度人臉處理2. 顏色校正策略**五、模型下載清單****六、性能…

如何在WordPress中選擇最佳Elementor主題:專家指南

當你在WordPress建站過程中逐步積累了經驗&#xff0c;你可能會發覺&#xff0c;基礎和進階主題已難以完全滿足你的需求。如果你需要更復雜的功能、更靈活的布局設計&#xff0c;甚至高級定制效果&#xff0c;那么就需要選擇更加專業的主題。在這篇文章中&#xff0c;我將為你推…

FPGA高速接口 mipi lvds cameralink hdml 千兆網 sdi

mipi: https://blog.csdn.net/SDJ_success/article/details/146541776 cameralink CameraLink協議 CameraLink協議是一種專門針對機器視覺應用領域的串行通信協議&#xff0c;它使用低壓差分信號(LVDS)進行數據的傳輸和通信。CameraLink標準是在ChannelLink標準的基礎上多加了…

手機收不到WiFi,手動輸入WiFi名稱進行連接不不行,可能是WiFi頻道設置不對

以下是電腦上分享WiFi后&#xff0c;部分手機可以看到并且能連接&#xff0c;部分手機不行&#xff0c;原因是&#xff1a;頻道設置為5GHz&#xff0c;修改成&#xff0c;任何可用頻率&#xff0c;則可

12.Java 對象冷凍術:從用戶登錄到游戲存檔的序列化實戰

目錄 一、引言 二、用戶登錄存檔&#xff1a;讓賬號信息「凍齡」不變 1. 給對象貼「冷凍標簽」&#xff1a;實現 Serializable 2. 冷凍與解凍實戰&#xff1a;把用戶存進文件 3. 演示場景 三、游戲存檔復活&#xff1a;讓角色進度「穿越時空」 1. 復雜對象冷凍&#xff…

conda 環境中opencv 報錯以及其他報錯

如題&#xff0c;通過 conda install opencv 然后遇到 ImportError: DLL load failed while importing cv2: 找不到指定的模塊。 參考網絡相關答案 通過conda 卸載 然后通過 pip3 安裝opencv-pyhton https://stackoverflow.com/questions/75387197/anaconda-importerror-dll-…

(已開源-CVPR2024) RadarDistill---NuScenes數據集Radar檢測第一名

本文介紹一篇Radar 3D目標檢測模型&#xff1a;RadarDistill。雷達數據固有的噪聲和稀疏性給3D目標檢測帶來了巨大挑戰。在本文中&#xff0c;作者提出了一種新的知識蒸餾(KD)方法RadarDistill&#xff0c;它可以通過利用激光雷達數據來提高雷達數據的表征。RadarDistill利用三…

創建型設計模式之Singleton(單例)設計模式

創建型設計模式之Singleton&#xff08;單例&#xff09;設計模式 摘要&#xff1a; Singleton&#xff08;單例&#xff09;設計模式確保一個類僅有一個實例&#xff0c;并提供全局訪問點。其結構包含一個靜態方法getInstance()用于獲取唯一實例&#xff0c;構造方法私有化防…