介紹
訪問者模式的基本思想是累舷,軟件系統(tǒng)中擁有一個由許多對象構(gòu)成的,比較穩(wěn)定的對象結(jié)構(gòu)拔稳,這些對象的類都擁有一個 accept 方法用來接收訪問者對象的訪問(這個方法需要的參數(shù)為訪問者類校哎,調(diào)用訪問者類的方法完成訪問),訪問者是一個接口滔蝉,它擁有一個 visit 方法击儡,這個方法對訪問到的對象結(jié)構(gòu)中不同類型的元素作不同的處理。在對象結(jié)構(gòu)的一次訪問過程中蝠引,我們遍歷整個對象結(jié)構(gòu)(這里的整個對象結(jié)構(gòu)可以理解為類似集合阳谍,就是說這些被訪問的對象都可以通過遍歷得到)蛀柴,對每一個元素都實施 accept 方法,在每一個元素的 accept 方法中又會調(diào)用訪問者的 visit 方法矫夯,從而使訪問者可以處理對象結(jié)構(gòu)的每一個元素鸽疾,我們可以針對對象結(jié)構(gòu)設(shè)計不同的訪問者類來完成不同的操作,達(dá)到區(qū)別對待的效果训貌。
比較抽象不好理解制肮,這里可以理解為,公司有五種員工對應(yīng)上面的對象結(jié)構(gòu)也就是被訪問者递沪,還有兩種管理層對應(yīng)上面的訪問者豺鼻,兩種管理層都可以管理五種不同的員工,但是款慨,五種員工被兩種管理層管理的方式不一樣儒飒。
這時候可以我們定義的五種員工都有一個 accept 方法,可以將管理層對象傳入檩奠,兩個管理層對象中也分別定義了自己對五種員工不同管理的方法桩了,這樣在員工的 accept 方法中,調(diào)用相應(yīng)管理者的管理自己對應(yīng)的方法埠戳。這樣在遍歷管理五種員工時圣猎,就可以通過傳入不同的管理層達(dá)到不同的管理效果。
定義
封裝一些作用于某些數(shù)據(jù)結(jié)構(gòu)中各元素的操作乞而,它可以在不改變這個數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作送悔。
使用場景
對象結(jié)構(gòu)比較穩(wěn)定,但經(jīng)常需要在此對象結(jié)構(gòu)上定義新的操作 比如上例中爪模,五種員工比較穩(wěn)定不會變欠啤,又來了董事長可以管理這五種員工,但是他的管理跟上面兩個管理層的還不一樣屋灌,這時候只需要定義一個董事長并實現(xiàn)對五種員工管理的 visit 方法即可
需要對一個對象結(jié)構(gòu)中的對象進(jìn)行很多不同且不相關(guān)的操作洁段,而需要避免這些操作 "污染這些類",也不希望在增加新操作時修改這些類共郭。 還是以上例來說祠丝,如果我們在五種員工中定義不同管理者訪問他們的方法,那么每次需要新加管理者時都需要在五種員工類中增加方法除嘹,或者某種管理層的管理方法有變化時這五個類都得改写半,太不面向?qū)ο罅耍园压芾韺映橄蟪鰜砦竟荆黾庸芾韺訒r或者管理層邏輯改變時都不影響五種員工類叠蝇。
角色介紹
Visitor 接口或者抽象類,它定義了對每一個元素 (Element) 訪問的行為年缎,它的參數(shù)就是可以訪問的元素悔捶,它的方法個數(shù)理論上來講與元素個數(shù)是一樣的铃慷,因此,訪問者模式要求元素的類族要穩(wěn)定(上例中蜕该,五種員工類別不能改)犁柜,如果經(jīng)常添加、移除元素類堂淡,必然會導(dǎo)致頻繁地修改 Visitor 接口赁温,如果出現(xiàn)這種情況,說明不適合使用訪問者模式淤齐。
ConcreteVisitor 具體的訪問者,它需要給出每一個元素類訪問時所產(chǎn)生的具體行為
Element 元素接口或抽象類袜匿,它定義了一個接受訪問者(accept)的方法更啄,其意義是值每一個元素都要可以被訪問者訪問。
ElementA/ElementB 具體的元素類居灯,它提供接受訪問方法的具體實現(xiàn)祭务,而這個具體的實現(xiàn),通常情況下是使用訪問者提供的訪問該元素類的方法
ObjectStructure 定義當(dāng)中所提到的對象結(jié)構(gòu)怪嫌,對象結(jié)構(gòu)是一個抽象表述义锥,它內(nèi)部管理了元素集合,并且可以迭代這些元素訪問者訪問岩灭。
Android 源碼中的訪問者模式 - 編譯期注解
編譯注解核心原理依賴 APT(Annotation Processing Tools)拌倍,編譯期注解的工作過程就是使用了訪問者模式,具體編譯期注解的工作過程噪径,會寫一篇新的文章來分析柱恤。
優(yōu)點
個角色職責(zé)分離,符合單一職責(zé)原則
具有優(yōu)秀的擴(kuò)展性
使得數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作解耦找爱,使得操作集合可以獨立變化
靈活性
缺點
- 具體元素對訪問者公布細(xì)節(jié)梗顺,違反了迪米勒原則
- 具體元素變時導(dǎo)致修改成本大
- 違反了依賴導(dǎo)致原則,為了達(dá)到 “區(qū)別對待” 而依賴了具體類车摄,沒有依賴對象寺谤。