設計模式(十四)行為型模式---訪問者模式(visitor)

文章目錄

  • 訪問者模式簡介
  • 分派的分類
  • 什么是雙分派?
  • 結構
  • UML圖
  • 具體實現
    • UML圖
    • 代碼實現
  • 優缺點

訪問者模式簡介

  • 訪問者模式(visitor pattern)是封裝一些作用于某種數據結構中的元素的操作,它可以在不改變這個數據結構(實現例子中的、男女)的前提下,定義作用于這些原則新的操作(實現例子中的成功、失敗、待定等結果)。

分派的分類

  • 靜態分派:就是程序編譯的時候,根據參數類型就可以確定的分派。
  • 動態分派:因為參數是父類或者接口,具體由誰執行需要根據接口傳入參數具體類型確定的分派。

什么是雙分派?

  • 雙分派:就是經歷兩次上面的分派過程就是雙分派。

結構

  • 1.抽象訪問者角色(Visitor):定義了對每一個原色(Element)訪問的行為,他的參數就是可以訪問的元素,他的方法個數理論上和元素個數是一致的,所以訪問者模式要求元素類的個數不能改變。
  • 2.具體訪問者角色(Concrete Visitor):給出對每一個元素訪問時所產生的具體行為(demo中的成功、失敗、待定)
  • 3.抽象元素角色(Element):定義了一個接受訪問者的方法(accept),其意思就是每一個元素都可以被訪問者訪問。
  • 4.具體元素就角色(Concrete Element):提供了接受訪問方法的具體實現,這個具體實現,通常情況下是使用訪問者提供的訪問該元素的方法。
  • 5.對象結構角色(Object Structure):可以理解為具體元素的存儲容器。

UML圖

在這里插入圖片描述

具體實現

例子:好聲音,對男女選手進行評審。

UML圖

在這里插入圖片描述

代碼實現

  • 抽象元素角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 抽象元素角色 提供一個方法讓訪問者可以訪問* @date 2024/5/26 0:18*/
public abstract class Person {/*** @description  提供給訪問者訪問的防方法,訪問者通過參數傳遞進來。* @author  xxliao* @date  2024/5/26 0:28*/public abstract void result(ActionVisitor actionVisitor);
}
  • 具體元素角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具體元素角色,接受一個訪問者方法* @date 2024/5/26 0:18*/
public class Man extends Person{/*** @description  具體元素角色提供給訪問者的防方法,訪問者通過參數傳遞進來* @author  xxliao* @date  2024/5/26 0:29*/@Overridepublic void result(ActionVisitor actionVisitor) {// 訪問者對象 獲取 本元素(man)對象的結果,將本對象自己傳遞進去,這里使用了雙分派actionVisitor.getManResult(this);}
}
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具體元素角色* @date 2024/5/26 0:19*/
public class Woman extends Person{/*** @description  具體元素角色提供給訪問者的防方法,訪問者通過參數傳遞進來* @author  xxliao* @date  2024/5/26 0:29*/@Overridepublic void result(ActionVisitor actionVisitor) {// 訪問者對象 獲取 本元素(woman)對象的結果,將本對象自己傳遞進去,這里使用了雙分派actionVisitor.getWomanResult(this);}
}
  • 抽象訪問者角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 抽象訪問者角色,角色內定義訪問方法,一般來說要包括所有的具體抽象元素* @date 2024/5/26 0:18*/
public abstract class ActionVisitor {/*** @description  Man get result* @author  xxliao* @date  2024/5/26 0:20*/public abstract void getManResult(Man man);/*** @description  Woman get result* @author  xxliao* @date  2024/5/26 0:20*/public abstract void getWomanResult(Woman woman);
}
  • 具體訪問者角色
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具體訪問者角色 -成功* @date 2024/5/26 0:22*/
public class SuccessActionVisitor extends ActionVisitor{@Overridepublic void getManResult(Man man) {System.out.println("man --- success");}@Overridepublic void getWomanResult(Woman woman) {System.out.println("woman --- success");}
}
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 具體訪問者角色 -失敗* @date 2024/5/26 0:22*/
public class FailActionVisitor extends ActionVisitor{@Overridepublic void getManResult(Man man) {System.out.println("man --- fail");}@Overridepublic void getWomanResult(Woman woman) {System.out.println("woman --- fail");}
}
  • 對象結構角色
package com.xxliao.pattern.behavioral.visitor.demo;import java.util.LinkedList;
import java.util.List;/*** @author xxliao* @description: 對象結構,需要定義存儲具體元素角色的容器,然后* @date 2024/5/26 0:24*/
public class ObjectStructure {// 定義存儲具體元素對象的容器private List<Person>  persons = new LinkedList<>();// 添加具體元素對象public void addPerson(Person person) {persons.add(person);}// 移除具體元素對象public void removePerson(Person person) {persons.remove(person);}/*** @description  顯示最后結果* @author  xxliao* @date  2024/5/26 0:35*/public void print(ActionVisitor actionVisitor){for (Person person : persons) {person.result(actionVisitor);}}
}
  • 測試客戶端
package com.xxliao.pattern.behavioral.visitor.demo;/*** @author xxliao* @description: 訪問者模式 測似客戶端* @date 2024/5/26 0:36*/
public class Client {public static void main(String[] args) {// 創建 對象結構ObjectStructure objectStructure = new ObjectStructure();// 添加具體元素對象objectStructure.addPerson(new Man());objectStructure.addPerson(new Woman());// 創建訪問者具體對象 --成功SuccessActionVisitor successActionVisitor = new SuccessActionVisitor();// 對象結構 顯示最后結果objectStructure.print(successActionVisitor);}
}
  • 測試結果
    在這里插入圖片描述

優缺點

  • 優點:.在元素個數不變的情況下,增加新功能(具體訪問者對象),做到了開閉原則。
  • 缺點:在元素個數要變化的情況下,所有的具體訪問者對象都要修改代碼, 不符合開閉原則。

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

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

相關文章

紅隊內網攻防滲透:內網滲透之windows內網權限提升技術:手工篇

紅隊內網攻防滲透 1. 內網權限提升技術1.1 windows內網權限提升技術--手工篇1.1.1 Web到Win-系統提權-人工操作1.1.1.1 信息收集1.1.1.2 補丁篩選1.1.1.3 EXP獲取執行1.1.2 Web到Win-系統提權-土豆家族1.1.2.1 Test in:Windows 10/11(1809/21H2)1.1.2.2 Test in:Windows Se…

全新市場階段,Partisia BlockChain 將向 RWA、DeFi 等領域布局

Partisia Blockchain 是一個全新范式的 Layer1&#xff0c;該鏈通過 MPC 方案來構建鏈上隱私方案&#xff0c;同時該鏈通過系列獨特且創新的設計&#xff0c;旨在進一步解決目前 Web3 中所面臨的不可能三角問題&#xff0c;包括安全性、互操作性和可擴展性&#xff0c;為更多的…

NTFS磁盤格式讀寫工具:Tuxera NTFS 2021 for Mac

Tuxera NTFS 是一款用于 macOS 系統的 NTFS 文件系統驅動程序。NTFS 是 Windows 系統中常用的文件系統&#xff0c;而 macOS 默認只支持讀取 NTFS 格式的磁盤&#xff0c;不能進行寫入操作。因此&#xff0c;如果你需要在 macOS 上進行 NTFS 磁盤的寫入操作&#xff0c;就需要安…

提交一個Bug需要哪些信息?

軟件在使用過程中存在的任何問題都叫做軟件的缺陷&#xff0c;簡稱Bug&#xff0c;我認為要提交一個Bug首先得將這個Bug的核心內容說明一下&#xff0c;比如Bug的核心問題是什么、產生的前提、預期結果是什么、但實際結果是什么、以及附上一個證據圖片。 然后提交時需要Bug報告…

【一刷《劍指Offer》】面試題 28:字符串的排列

牛客對應題目鏈接&#xff1a;字符串的排列_牛客題霸_牛客網 (nowcoder.com) 力扣對應題目鏈接&#xff1a;LCR 157. 套餐內商品的排列順序 - 力扣&#xff08;LeetCode&#xff09; 核心考點 &#xff1a;全排列問題&#xff0c; DFS。 一、《劍指Offer》對應內容 二、分析題…

JS(DOM、事件)

DOM 概念:Document Object Model&#xff0c;文檔對象模型。將標記語言的各個組成部分封裝為對應的對象: Document:整個文檔對象Element:元素對象Attribute:屬性對象Text:文本對象Comment:注釋對象 JavaScript通過DOM&#xff0c;就能夠對HTML進行操作: 改變 HTML 元素的內…

Windows端口本地轉發

參考 微軟Netsh interface portproxy 命令 界面端口代理的 Netsh 命令 | Microsoft Learn 使用Windows系統的portproxy功能配置端口轉發 使用Windows系統的portproxy功能配置端口轉發-阿里云幫助中心 (aliyun.com) 將來自0.0.0.0地址對端口35623的訪問轉發到172.18.106.16…

SpringBoot @ModelAttribute注解的深入指南

文章目錄 前言一、基本概念二、方法級別的@ModelAttribute1. 用途2. 示例三、參數級別的@ModelAttribute1. 用途2. 示例四、處理多個@ModelAttribute1. 示例五、繼承與@ModelAttribute注解的結合使用1. 示例1.1 基類(父類)1.2 子類(具體控制器)<

多維數組找最大值

調用JavaScript的一個內置函數&#xff1a;Math.max() <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

虛擬機VMware Workstation 常用的快捷方式

1、 虛擬機軟件&#xff0c;如 VMware Workstation、VirtualBox 等 所使用的是 VMware Workstation 2、快捷方式 2.1 切換鼠標和鍵盤焦點 CtrlAlt&#xff1a;從虛擬機中釋放鼠標和鍵盤&#xff0c;回到主機 2.2 全屏模式 2.2.1 進入全屏模式: CtrlAltEnter 2.2.2 退出全…

政安晨:【Keras機器學習示例演繹】(五十一)—— 利用廣義網絡、深度網絡和交叉網絡進行結構化數據學習

政安晨的個人主頁&#xff1a;政安晨 歡迎 &#x1f44d;點贊?評論?收藏 收錄專欄: TensorFlow與Keras機器學習實戰 希望政安晨的博客能夠對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出指正&#xff01; 本文目標&#xff1a;使用 "寬深 "和 …

Python 技能提升(三)

global 和 nonlocal b 全局變量 global variabledef foo():a 局部變量 local variable# 在局部里面操作全局變量&#xff0c;需要加上聲明global bb b &#xff01;&#xff01;&#xff01;print(b)foo() # 全局變量 global variable&#xff01;&#xff01;&#xff01…

Python 遞歸函數一例

現有示例數據 # 示例數據 pending_join [ {increment: "department Finance", statement_index: 0}, {increment: "name Lisa", statement_index: 2}, {increment: "gender Female", statement_index: 3}, {increment: "hire_date <…

redis如何實現分布式鎖

Redisson是怎么實現分布式鎖的 分布式鎖&#xff1a;Redisson 提供了一種簡單而強大的方式來實現分布式鎖。 它支持多種鎖模式&#xff0c;如公平鎖、可重入鎖、讀寫鎖等&#xff0c;并且提供了鎖的超時設置和自動釋放功能。 鎖的獲取 在Redisson中常見獲取鎖的方式有 lock() …

【代碼隨想錄訓練營】【Day 37】【貪心-4】| Leetcode 840, 406, 452

【代碼隨想錄訓練營】【Day 37】【貪心-4】| Leetcode 840, 406, 452 需強化知識點 python list sort的高階用法&#xff0c;兩個key&#xff0c;另一種逆序寫法python list insert的用法 題目 860. 檸檬水找零 思路&#xff1a;注意 20 塊找零&#xff0c;可以找3張5塊升…

Mysql基礎教程(13):GROUP BY

MySQL GROUP BY 【 GROUP BY】 子句用于將結果集根據指定的字段或者表達式進行分組。 有時候&#xff0c;我們需要將結果集按照某個維度進行匯總。這在統計數據的時候經常用到&#xff0c;考慮以下的場景&#xff1a; 按班級求取平均成績。按學生匯總某個人的總分。按年或者…

“世界酒中國菜”系列活動如何助推鄉村振興和文化交流?

"世界酒中國菜"系列活動如何助推鄉村振興和文化交流&#xff1f; 《經濟參考報》&#xff08;2024年5月24日 第6版&#xff09; 新華社北京&#xff08;記者 張曉明&#xff09; “世界酒中國菜”系列活動自啟動以來&#xff0c;已在國內外產生了廣泛影響。這一國家…

mysql面試之分庫分表總結

文章目錄 1.為什么要分庫分表2.分庫分表有哪些中間件&#xff0c;不同的中間件都有什么優點和缺點&#xff1f;3.分庫分表的方式(水平分庫,垂直分庫,水平分表,垂直分表)3.1 水平分庫3.2 垂直分庫3.3 水平分表3.4 垂直分表 4.分庫分表帶來的問題4.1 事務一致性問題4.2 跨節點關聯…

【退役之重學 SQL】什么是笛卡爾積

一、初識笛卡爾積 概念&#xff1a; 笛卡爾積是指在關系型數據庫中&#xff0c;兩個表進行 join 操作時&#xff0c;沒有指定任何條件&#xff0c;導致生成的結果集&#xff0c;是兩個表中所有行的組合。 簡單來說&#xff1a; 笛卡爾積是兩個表的乘積&#xff0c;結果集中的每…

力扣 454題 四數相加Ⅱ 記錄

題目描述 給你四個整數數組 nums1、nums2、nums3 和 nums4 &#xff0c;數組長度都是 n &#xff0c;請你計算有多少個元組 (i, j, k, l) 能滿足&#xff1a; 0 < i, j, k, l < n nums1[i] nums2[j] nums3[k] nums4[l] 0示例 1&#xff1a; 輸入&#xff1a;nums1 …