【設計模式】趣說訪問者模式,頗有些無奈之舉

来源:https://www.cnblogs.com/lixinjie/archive/2020/05/24/a-post-about-designpattern-of-visitor.html
-Advertisement-
Play Games

老實說,在實際編程中,訪問者設計模式應用的並不多,至少我是這樣認為的,因為它的主要使用場景並不多。那麼肯定會有人問,訪問者模式的主要使用場景是什麼呢?繼續往下看便知。新聞聯播看多了之後首先要說的是,設計模式中的“訪問者”和現實生活中的“訪問者”其本質是一回事。雖然設計模式中的不太熟悉,但現實生活中的 ...



老實說,在實際編程中,訪問者設計模式應用的並不多,至少我是這樣認為的,因為它的主要使用場景並不多。

那麼肯定會有人問,訪問者模式的主要使用場景是什麼呢?繼續往下看便知。


新聞聯播看多了之後


首先要說的是,設計模式中的“訪問者”和現實生活中的“訪問者”其本質是一回事。雖然設計模式中的不太熟悉,但現實生活中的再熟悉不過了。

我在以前的文章中多次提到過,有時站在現實生活的角度看待某些技術點反而會更容易看清楚,那照例還是從生活中的事情說起吧。

說起訪問者,我能夠想到最高大上的,莫過於國家領導人的國事訪問。以中方訪問美方來說吧,這裡面的大致內容(我猜)應該是這樣的:

中方專機什麼時間在哪個機場降落,美方派誰在機場迎接,然後就是歡迎儀式和歡迎晚宴,接著就是會見哪些人,開哪些會議,簽署哪些文件,參觀哪些地方等等,最後就是結束訪問啟程回國。

當然這些內容肯定是雙方外交部門都提前溝通好的。但是仍然是在美方的安排下一步一步進行,因為我們是作為訪客的身份,人家是東道主,要盡地主之誼的。(雖然老美不是什麼好東西)

比如人家安排的吃牛排,那我們就吃吧。我們總不能要求他們改成“主席套餐”吧,再說他們的廚師也搞定啊。

等到老美的總統來我們國家訪問的時候,他們就成了訪客了,我們就是東道主,整體就得由我們來安排。讓他喝稀飯他就不能吃大米,不喜歡吃就晚上自己回酒店泡速食麵,哈哈哈哈。

如果把這個事情抽象一下就是,一方在另一方的安排下,逐步有序的做一些事情。


自己想體驗的話就來個這吧


國事訪問這事啊離我們太遙遠了,那就再看個和我們息息相關的吧。沒錯,就是旅游。無論是國內游還是出境游,其實差別不大,大致內容應該是這樣的:

先報好旅行社,在指定的時間乘坐交通工具到達目的地後,會有一輛大巴車拉著我們,按照行程開始去景點,去吃飯,去酒店等等。

我們什麼都不用操心,跟著走就行了,因為旅行社和導游都安排好了。再說了,即我們使有意見,導游也不會聽我們的。

頗令人討厭的可能就是逛購物店了,但是沒辦法,因為協議已經簽了。我們有義務進購物店,聽相關人員講解,想買的就買,不想買的隨便看看,但是不能提前出去。

其實還有更坑的,那就是導游在大巴車上強行收費,說些很難聽的話,甚至罵人/威脅。尤其是在境外,他們覺得此生很難再見面,有時話說的特別難聽。

所以整個行程下來,既有高興的時候,也有心煩的時候。導游給我們講解當地歷史的時候,覺得他是“好人”,領我們進購物店時,又覺得他是“壞人”。

其實都不是,他是“工人”,一個從事旅游行業工作的人。一個需要養家糊口的人,跟我們沒啥區別。我是不是很善解人意啊。

如果把這個事情也抽象一下就是,必須按照既定的規則走完所有事項,如果對某個事項關心,那就積極的去獲取自己想要的信息,如果對某個事項不關心,那就默默的跟隨即可,什麼都不用做,但是不准離開。


做一個善於思考總結的人


我想說的是既然報團游有如此多的問題,為什麼還有那麼多人報團,而不選自由行呢。答案是顯而易見的。

以出境游來說,當你達到國外,人生地不熟,語言又不通,很多事情的推進會特別艱難。

當然也可以提前研究攻略,制定好路線,訂好酒店機票等。但是旅游主要是想放鬆一下,為了出國一周,在家看三個月攻略,豈不是更累嗎?

總結一下,當你對所要做的事情完全不瞭解,而且想要瞭解的話需花費很大的精力時,只能選擇第三方給出的方案,雖然明知裡面可能會有坑。

對於像國事訪問的,因為有許多禮儀禮節或規則約束需要遵守,所以一般也都聽從東道主的安排。

雖然出訪和旅游這兩件事的本質完全不一樣,但是他們的巨集觀進行模式卻基本一致。

到此我們已經講了兩件事,兩個特點,兩個原因。請仔細體會下。看起來有點讓人不爽,但又頗有些無奈。

這兩件事都是站在“訪問者”的立場來說的,下麵從多角度來看下。


從一個具體的示例說起


假如小明在北京工作多年,對北京非常熟悉。他的朋友小白來找他玩,而且是第一次來北京,打算去一些有名的景點。

在這件事中,小明就是東道主,小白就是訪客。其實就是一方帶另一方參觀嘛。

站在東道主的角度,他要安排訪客參觀景點,所以是這樣的:

/**
 * <p>東道主
 */

public interface Host {

    //帶朋友去故宮
    void show(PalaceMuseum PalaceMuseum, Guest guest);

    //帶朋友去長城
    void show(GreatWall GreatWall, Guest guest);

    //帶朋友去頤和園
    void show(SummerPalace SummerPalace, Guest guest);
}

 


站在訪客的角度,他是要參觀景點的,所以是這樣的:

/**
 * <p>客人
 */

public interface Guest {

    //看故宮
    void look(PalaceMuseum PalaceMuseum);

    //看長城
    void look(GreatWall GreatWall);

    //看頤和園
    void look(SummerPalace SummerPalace);
}



站在景點的角度,它是要接受訪客的參觀的,所以是這樣的:

/**
 * <p>故宮
 */

public interface PalaceMuseum {

    //讓訪客看
    void accept(Guest guest);
}

/**
 * <p>長城
 */

public interface GreatWall {

    //讓訪客看
    void accept(Guest guest);
}

/**
 * <p>頤和園
 */

public interface SummerPalace {

    //讓訪客看
    void accept(Guest guest);
}

 

 

在這個事件中共有三種角色,它們的職責、目的和作用都非常清晰:

小明:東道主,職責是負責協助

小白:訪客,目的是欣賞景點的景色

景點:被欣賞者,作用是提供景色

這就是一個訪問者的模型,我們把它抽象並一般化,發現這是一個固定的套路或模式,稱之為訪問者模式。

在訪問者模式中,共有三方參與者,它們的分工非常明確:

一方:訪問者,獲取信息的人

二方:被訪問者,提供信息的人

三方:協調者,安排一二雙方進行交互的人

可以這樣來理解三方的定位,一方是購買者(出錢),二方是提供者(出力),三方是協調者(和稀泥)。哈哈。

註意,這裡的一方二方三方都是訪問者模式內部的概念,它們是一家人或一個單位的。

換個角度來看就是,訪問者在協調者制定的規則下完成對被訪問者的訪問,期間獲取關心的信息,忽略不關心的信息。

把訪問者模式放到一個巨集觀應用中,應該是這樣的:


用戶程式->|訪問者->協調者->被訪問者|->底層複雜數據



訪問者模式的推導


對於設計模式,一定要活學活用,不能拘泥於GOF。一定要按自己的場景需求來用,不能死搬硬套。

在訪問者模式中,通常把被訪問者稱為元素,訪問者自然還是訪問者,抽象一下:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事務的使用方式 事務的錯誤處理 WATCH命令 生存時間 緩存策略 Redis中的事務(transaction)是一組命令的集合。事務同命令一樣都是Redis的最小執行單位,一個事務中的命令要麼都執行,要麼都不執行。 事務的原理是先將屬於一個事務的命令發送給Redis,然後再讓Redis依次執行這些 ...
  • 摘要 本文旨在瞭解MySQL InnoDB引擎如何支持事務的隔離級別。 文章主要內容分兩個部分。 第一部分闡述資料庫的併發問題以及為之產生的ANSI SQL 標準隔離級別。 第二部分根據 MySQL 官方文檔解釋 InnoDB 是如何支持這些隔離級別的。 資料庫事務的併發問題 ANSI SQL 隔離 ...
  • 從 Gradle 角度看,Android 插件是由 Google 的 Android 團隊開發的一個第三方插件。 從 Android 的角度看,Android 插件是基於 Gradle 構建的,是和 Android studio 完美搭配的新一代構建系統。 ...
  • 目錄:andorid jar/庫源碼解析 Apktool.jar: 作用: 1、用於對APK文件進行解包,成可以讀的smali和xml,png等資源文件。 2、同時,把解碼之後的數據,重新打包成APK文件。 慄子: 使用命令的方式使用 1、apktool d xxx.apk // 解碼 apk文件 ...
  • 一,JavaScript是什麼? 1,JavaScript簡稱:js,是一種瀏覽器解釋型語言,嵌套在HTML文件中交給瀏覽器解釋執行。主要用來實現網頁的動態效果,用戶交互及前後端的數據傳輸等。 2,JavaScript 組成 1,核心語法 - ECMAScript (ES5-ES6) 規範了Java ...
  • 在開發大型Web應用或複雜交互的網站,不免會遇到一些頁面性能瓶頸的問題。本篇介紹一下如何利用Chrome的性能面板分析網站的性能瓶頸,應該對你有所幫助。 註意,為了減少一些Chrome插件對性能評估產生噪音,最好打開隱身模式訪問頁面進行測試。 將Chrome切換到隱身模式,然後打開該頁面進行測試: ...
  • 在組件特定時期,觸發的條件,統稱為生命周期; + 組件生命周期分為三部分: 組件創建階段 :組件創建階段的生命周期函數,有一個顯著的特點:創建階段的生命周期函數,組件一生只執行一次; componentWillMount:組件將要被掛載,此時還沒有開始渲染虛擬dom render:第一次開始渲染真正 ...
  • # 6.動畫 - 1. transition 過渡 transition-property:all;//監聽屬性 transition-duration:1s;//過渡時間 transition-timing-function:linear;//運動速率 transition-delay:1s;// ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...