訪問者模式【visitor pattern 】
以列印公司員工的資訊報表為例。下面先看下類圖。
使用了乙個模版方法模式,把所要的資訊都列印出來。這樣子寫出來的**就不太符合公司不同管理層的需要,不能滿足各自的需求。
每個普通員工類和經理類都乙個方法 report,那是否可以把這個方法提取到另外乙個類中來實現呢。最初的類圖如下:
兩個類中都有report()方法,那麼再進行一些改善。
這樣子就將report()方法提煉出來了,再看下下面這個。
在抽象類 employee 中增加了 accept 方法,這個方法是定義我這個類可以允許被誰來訪問,也就定義一類訪問者,在具體的實現類中呼叫訪問者的方法。
那在具體類中就可以設定訪問者了。
public
void
accept(ivisitor visitor)
在主類進行呼叫時直接傳入訪問者進行訪問公司不同角色的資訊。
for(employee emp:mockemployee())
再看一下他的通用類圖:
來看一下這幾個角色的職責:
抽象訪問者(visitor):抽象類或者介面,宣告訪問者可以訪問哪些元素,具體到程式中就是 visit方法的引數定義哪些物件是可以被訪問的;
具體訪問者(concretevisitor):訪問者訪問到乙個類後該怎麼幹(哎,這個別讀歪了),要做什麼事情;
抽象元素(element):介面或者抽象類,宣告接受那一型別的訪問者訪問,程式上是通過 accept 方法中的引數來定義;
具體元素: (concreteelement):實現 accept 方法,通常是 visitor.visit(this),基本上都形成了乙個套路了;
結構物件(objectstruture):容納多個不同類、不同介面的容器,比如 list、set、map 等,在專案中,一般很少抽象出來這個角色;
總結:
應用場景:
先與迭代器模式比較一下,迭代器模式只能訪問同類或同介面的資料, (當然了,你使用 instanceof 的話,能訪問所有的資料,這個不爭論) ,而訪問者模式是對迭代器模式的擴充,可以遍歷不同的物件,然後執行不同的操作,也就是針對訪問的物件不同,執行不同的操作。故可以將訪問者模式應用到遍歷不同的物件,然後執行不同的操作的專案當中。比如統計(統計公司人員的工資等)、有多個訪問者的情況(上述的訪問者其實可以再進行細分,乙個用於展示報表的資訊,乙個用於計算報表中的一些資訊)、充當***(以後進行補充)。
優點
(1)符合單一職責原則,具體元素角色也就是employee 這個類的兩個子類負責資料的載入,而visitor 類則負責報表的展現,兩個不同的職責非常明確的分離開來,各自演繹而變化。
(2)由於職責分開,繼續增加對資料的操作是非常快捷的。擴充套件性良好。
缺點:
(1)訪問者要訪問乙個類就必然要求這個類公布一些方法,也就是說訪問者關注了其他類的內部細節,這是迪公尺特法則所不建議的;
(2)具體角色的增加刪除修改都是比較苦難的,就上面那個例子,你想想,你要是想增加乙個成員變數,比如年齡 age,visitor 就需要修改,如果 visitor 是乙個還好說,多個呢?業務邏輯再複雜點呢。
設計模式(JAVA) 訪問者模式
場景 將公司中所有人員資訊都列印匯報出來,其中假設公司有兩類人員 1.普通員工 2.管理層 不同人員型別的資訊是不同的。訪問者模式 定義 封裝一些作用於某種資料結構中的各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作。包含如下幾個角色 1.visitor 抽象訪問者 抽象類或...
JAVA設計模式 訪問者模式
訪問者模式一般被使用者一些資料結構穩定的場合,資料物件穩定,而實際對它的操作是不穩定的,他可以接受不同的物件而做出不同的反應,對與穩定的資料結構,它的功能和方法也就穩定,所以就把它抽象出來,抽取出來,而對於訪問它的物件是經常改變的,傳遞不同的實際物件也就得到不同的執行效果,多型的體現 訪問者模式的參...
Java設計模式 訪問者模式
定義 封裝某些作用於某種資料結構中各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作。class a public void method2 b b class b 看一下在類a中,方法method1和方法method2的區別在 方法method1很簡單,就是列印出一句 我是a...