知識(shí)整理NO.5#訪問者模式Visitor

訪問者模式Visitor

背景

1.概述

  • 在軟件開發(fā)過程中,對(duì)于系統(tǒng)中的某些對(duì)象,它們存儲(chǔ)在同一個(gè)集合collection中涉馁,且具有不同的類型,而且對(duì)于該集合中的對(duì)象爱致,可以接受一類稱為訪問者的對(duì)象來訪問烤送,而且不同的訪問者其訪問方式有所不同

2.問題

  • 對(duì)同一集合對(duì)象的操作并不是唯一的,對(duì)相同的元素對(duì)象可能存在多種不同的操作方式糠悯。而且這些操作方式并不穩(wěn)定帮坚,如果對(duì)需要增加新的操作妻往,如何滿足新的業(yè)務(wù)需求?

3.解決方案

  • 訪問者模式:表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作试和。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作讯泣。

  • 1)訪問者模式中對(duì)象結(jié)構(gòu)存儲(chǔ)了不同類型的元素對(duì)象,以供不同訪問者訪問阅悍。
    2)訪問者模式包括兩個(gè)層次結(jié)構(gòu)好渠,一個(gè)是訪問者層次結(jié)構(gòu),提供了抽象訪問者和具體訪問者节视,一個(gè)是元素層次結(jié)構(gòu)拳锚,提供了抽象元素和具體元素。
    相同的訪問者可以不同的方式訪問不同的元素寻行,相同的元素可以接受不同訪問者以不同訪問方式訪問霍掺。在訪問者模式中,增加新的訪問者無須修改原有系統(tǒng)拌蜘,系統(tǒng)具有較好的可擴(kuò)展性

剖析

定義

  • 表示一個(gè)作用于某個(gè)對(duì)象結(jié)構(gòu)中各元素的操作杆烁。它使你可以再不改變各元素的類的前提下定義這些元素的新操作。
  • 1)訪問者模式中對(duì)象結(jié)構(gòu)存儲(chǔ)了不同類型的元素對(duì)象简卧,以供不同訪問者訪問兔魂。
  • 2)訪問者模式包括兩個(gè)層次結(jié)構(gòu),一個(gè)是訪問者層次結(jié)構(gòu)贞滨,提供了抽象訪問者和具體訪問者入热,一個(gè)是元素層次結(jié)構(gòu),提供了抽象元素和具體元素晓铆。
    相同的訪問者可以以不同的方式訪問不同的元素勺良,相同的元素可以接受不同訪問者以不同訪問方式訪問。在訪問者模式中骄噪,增加新的訪問者無須修改原有系統(tǒng)尚困,系統(tǒng)具有較好的可擴(kuò)展性

本質(zhì)

  • 預(yù)留通路,回調(diào)實(shí)現(xiàn)

UML

Visitor-UML.png

模式組成

  • 抽象訪問者(Vistor): — 為該對(duì)象結(jié)構(gòu)中ConcreteElement的每一個(gè)類聲明一個(gè)Visit操作链蕊。該操作的名字和特
  • 征標(biāo)識(shí)了發(fā)送Visit請(qǐng)求給該訪問者的那個(gè)類事甜。這使得訪問者可以確定正被訪問元素
  • 的具體的類。這樣訪問者就可以通過該元素的特定接口直接訪問它滔韵。
  • 具體訪問者(ConcreteVisitor): — 實(shí)現(xiàn)每個(gè)由Visitor聲明的操作逻谦。每個(gè)操作實(shí)現(xiàn)本算法的一部分,而該算法片斷乃是
  • 對(duì)應(yīng)于結(jié)構(gòu)中對(duì)象的類陪蜻。ConcreteVisitor為該算法提供了上下文并存儲(chǔ)它的局部狀態(tài)邦马。
  • 這一狀態(tài)常常在遍歷該結(jié)構(gòu)的過程中累積結(jié)果。
  • 抽象元素(Element):定義一個(gè)Accept操作,它以一個(gè)訪問者為參數(shù)滋将。
  • 具體元素(ConcreteElement): 實(shí)現(xiàn)Accept操作邻悬,該操作以一個(gè)訪問者為參數(shù)。
  • 對(duì)象結(jié)構(gòu)(ObjectStructure): 能枚舉它的元素随闽「阜幔可以提供一個(gè)高層的接口以允許該訪問者訪問它的元素【蛳埽可以是一個(gè)復(fù)合或是一個(gè)集合蛾扇,如一個(gè)列表或一個(gè)無序集合。

何時(shí)使用

  • 一個(gè)復(fù)雜的對(duì)象結(jié)構(gòu)包含很多其他對(duì)象魏滚,他們有不同的接口屁桑,但是想對(duì)這些對(duì)象實(shí)施一些依賴于具體類型的操作。
  • 需要對(duì)一個(gè)組合結(jié)構(gòu)中的對(duì)具體對(duì)象進(jìn)行很多不相關(guān)的操作栏赴,但是不想比這些對(duì)象“污染”這些對(duì)象的類,可以將相關(guān)的操作集中起來靖秩,定義一個(gè)訪問者類中须眷,并在需要在訪問者中定義的操作時(shí)使用它。
  • 定義復(fù)雜的類很少做修改沟突,但經(jīng)常需要向其添加新的操作花颗。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • ?使得增加新的訪問操作變得很容易。如果一些操作依賴于一個(gè)復(fù)雜的結(jié)構(gòu)對(duì)象的話惠拭,那么一般而言扩劝,增加新的操作會(huì)很復(fù)雜。而使用訪問者模式职辅,增加新的操作就意味著增加一個(gè)新的訪問者類棒呛,因此,變得很容易域携。
  • ?將有關(guān)元素對(duì)象的訪問行為集中到一個(gè)訪問者對(duì)象中簇秒,而不是分散到一個(gè)個(gè)的元素類中。
  • ?訪問者模式可以跨過幾個(gè)類的等級(jí)結(jié)構(gòu)訪問屬于不同的等級(jí)結(jié)構(gòu)的成員類秀鞭。迭代子只能訪問屬于同一個(gè)類型等級(jí)結(jié)構(gòu)的成員對(duì)象趋观,而不能訪問屬于不同等級(jí)結(jié)構(gòu)的對(duì)象。訪問者模式可以做到這一點(diǎn)锋边。
  • ?讓用戶能夠在不修改現(xiàn)有類層次結(jié)構(gòu)的情況下皱坛,定義該類層次結(jié)構(gòu)的操作。
  • 好的擴(kuò)展性 復(fù)用性 豆巨;分離無關(guān)行為剩辟,

缺點(diǎn):

  • ?增加新的元素類很困難。在訪問者模式中,每增加一個(gè)新的元素類都意味著要在抽象訪問者角色中增加一個(gè)新的抽象操作抹沪,并在每一個(gè)具體訪問者類中增加相應(yīng)的具體操作刻肄,違背了“開閉原則”的要求。
  • ?破壞封裝融欧。訪問者模式要求訪問者對(duì)象訪問并調(diào)用每一個(gè)元素對(duì)象的操作敏弃,這意味著元素對(duì)象有時(shí)候必須暴露一些自己的內(nèi)部操作和內(nèi)部狀態(tài),否則無法供訪問者訪問噪馏。
  • 對(duì)象結(jié)構(gòu)變化困難麦到,破壞了封裝
  • 具體元素對(duì)訪問者公布細(xì)節(jié)
  • 具體元素變更比較困難
  • 違背了依賴倒轉(zhuǎn)原則

總結(jié)

相關(guān)模式

  • ?迭代器模式:由于訪問者模式需要對(duì)對(duì)象結(jié)構(gòu)進(jìn)行操作,而對(duì)象結(jié)構(gòu)本身是一個(gè)元素對(duì)象的集合欠肾,因此訪問者模式經(jīng)常需要與迭代器模式聯(lián)用瓶颠,在對(duì)象結(jié)構(gòu)中使用迭代器來遍歷元素對(duì)象。
  • ?組合模式:在訪問者模式中刺桃,元素對(duì)象可能存在容器對(duì)象和葉子對(duì)象粹淋,因此可以結(jié)合組合模式來進(jìn)行設(shè)計(jì)。

擴(kuò)展

傾斜的“開閉原則”
?訪問者模式以一種傾斜的方式支持“開閉原則”瑟慈,增加新的訪問者方便桃移,但是增加新的元素很困難。
面向?qū)ο蟮脑O(shè)計(jì)原則中最重要的便是所謂的"開一閉"原則葛碧。一個(gè)軟件系統(tǒng)的設(shè)計(jì)應(yīng)當(dāng)盡量做到對(duì)擴(kuò)展開放借杰,對(duì)修改關(guān)閉。達(dá)到這個(gè)原則的途徑就是遵循"對(duì)變化的封裝"的原則进泼。這個(gè)原則講的是在進(jìn)行軟件系統(tǒng)的設(shè)計(jì)時(shí)蔗衡,應(yīng)當(dāng)設(shè)法找出一個(gè)軟件系統(tǒng)中會(huì)變化的部分,將之封裝起來乳绕。
很多系統(tǒng)可以按照算法和數(shù)據(jù)結(jié)構(gòu)分開绞惦,也就是說一些對(duì)象含有算法,而另一些對(duì)象含有數(shù)據(jù)刷袍,接受算法的操作翩隧。如果這樣的系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),又有易于變化的算法的話呻纹,使用訪問者模式就是比較合適的堆生,因?yàn)樵L問者模式使得算法操作的增加變得容易。
反過來雷酪,如果這樣一個(gè)系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)對(duì)象易于變化淑仆,經(jīng)常要有新的數(shù)據(jù)對(duì)象增加進(jìn)來的話,就不適合使用訪問者模式哥力。因?yàn)樵谠L問者模式中增加新的節(jié)點(diǎn)很困難蔗怠,要涉及到在抽象訪問者和所有的具體訪問者中增加新的方法墩弯。

總之,訪問者模式能給一系列對(duì)象透明地添加功能寞射,從而避免在維護(hù)期間對(duì)一系列對(duì)象進(jìn)行修改渔工,而且還能變相實(shí)現(xiàn)復(fù)用訪問者所具有的功能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市桥温,隨后出現(xiàn)的幾起案子引矩,更是在濱河造成了極大的恐慌,老刑警劉巖侵浸,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旺韭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掏觉,警方通過查閱死者的電腦和手機(jī)区端,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澳腹,“玉大人织盼,你說我怎么就攤上這事〗此” “怎么了悔政?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)延旧。 經(jīng)常有香客問我,道長(zhǎng)槽地,這世上最難降的妖魔是什么迁沫? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮捌蚊,結(jié)果婚禮上集畅,老公的妹妹穿的比我還像新娘。我一直安慰自己缅糟,他們只是感情好挺智,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窗宦,像睡著了一般赦颇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赴涵,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天媒怯,我揣著相機(jī)與錄音,去河邊找鬼髓窜。 笑死扇苞,一個(gè)胖子當(dāng)著我的面吹牛欺殿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳖敷,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼脖苏,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了定踱?” 一聲冷哼從身側(cè)響起棍潘,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屋吨,沒想到半個(gè)月后蜒谤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡至扰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鳍徽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敢课。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阶祭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出直秆,到底是詐尸還是另有隱情濒募,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布圾结,位于F島的核電站瑰剃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏筝野。R本人自食惡果不足惜晌姚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歇竟。 院中可真熱鬧挥唠,春花似錦、人聲如沸焕议。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盅安。三九已至唤锉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間别瞭,已是汗流浹背腌紧。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畜隶,地道東北人壁肋。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓号胚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親浸遗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猫胁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1 場(chǎng)景問題# 1.1 擴(kuò)展客戶管理的功能## 考慮這樣一個(gè)應(yīng)用:擴(kuò)展客戶管理的功能。 既然是擴(kuò)展功能跛锌,那么肯定是...
    七寸知架構(gòu)閱讀 2,900評(píng)論 1 58
  • 設(shè)計(jì)模式匯總 一弃秆、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,922評(píng)論 1 15
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案髓帽? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,734評(píng)論 1 92
  • 為什么喜歡上寫作呢菠赚?我經(jīng)常詢問自己,也渴望得到內(nèi)心真正的答案郑藏。 這是我以前的夢(mèng)想衡查,和菜頭說過,每個(gè)中國(guó)人都有個(gè)文藝...
    amazing2017閱讀 116評(píng)論 1 3
  • There are countless things out there on the internet that...
    章磊磊閱讀 1,751評(píng)論 4 20