文章首發:
行爲型模式:訪問者模式java
十一大行爲型模式之十一:訪問者模式。
姓名 :訪問者模式
英文名 :Visitor Pattern
價值觀 :來訪者即是客,招待就是
我的介紹 :
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
封裝一些做用於某種數據結構中的各元素的操做,它能夠在不改變數據結構的前提下定義做用於這些元素的新的操做。
(來自《設計模式之禪》)設計模式
先聲明一下,下面故事全瞎編的。。。數據結構
咱們是否還記得 N 年前反腐開始的時候,有一段時間提倡官員宴請吃飯只能幾菜幾湯,不能超出。我記得那會剛讀大一,軍事理論的老師說到這個問題,也發表了他的一些想法,他以爲這麼作比較刻板。今天的故事就和宴請有關。如今中國企業發展愈來愈大,在社會中擔任的責任也愈來愈大,政府也愈來愈重視企業,官員去參觀企業是常有的事,而企業宴請官員也變得格外的常見。ide
故事的背景就是企業宴請各級官員。不一樣級別的官員宴請的菜式就不同,每家企業的菜式豐富程度也不同。咱們這裏的訪問對象就用 Alibaba 和 Tencent 這 2 家公司,而訪問者就用郭嘉領導人和省領導人作舉例。這 2 家公司都跟喜來登酒店合做,Alibaba 合做方案是:宴請省領導人則十菜一湯,宴請郭嘉領導人則十四菜兩湯;Tencent 合做方案是:宴請省領導人則八菜一湯,宴請郭嘉領導人則十六菜兩湯。學習
下面看看如何用訪問者模式來實現上面的故事。測試
首先定義一個抽象類:企業。企業有一個共有的特性就是接受上級領導的訪問。this
/** * 企業 */ abstract class Company { public abstract void accept(Vistor vistor); }
上面故事咱們舉例了 2 家企業,分別是 Alibaba 和 Tencent,這裏實現這 2 家公司的宴請方案,並實現接待訪問者方法。spa
Alibaba 宴請郭嘉領導人是十四菜兩湯,宴請省領導是十菜一湯。設計
/** * Alibaba 企業 */ class AlibabaCompany extends Company { @Override public void accept(Vistor vistor) { vistor.visit(this); } public String entertainProvincialLeader() { return "Alibaba 接待省領導:十菜一湯"; } public String entertainNationalLeader() { return "Alibaba 接待郭嘉領導:十四菜兩湯"; } }
Tencent 宴請郭嘉領導人是十六菜兩湯,宴請省領導是八菜一湯。code
/** * Tencent 企業 */ class TencentCompany extends Company { @Override public void accept(Vistor vistor) { vistor.visit(this); } public String entertainProvincialLeader() { return "Tencent 接待省領導:八菜一湯"; } public String entertainNationalLeader() { return "Tencent 接待郭嘉領導:十六菜兩湯"; } }
這裏定義訪問者接口,訪問者接口有 2 個方法,分別是訪問 Alibaba 企業和訪問 Tencent 企業。
/** * 訪問者接口 */ interface Vistor { void visit(AlibabaCompany alibabaCompany); void visit(TencentCompany tencentCompany); }
上面故事中有 2 個訪問者,一個是郭嘉領導人,另外一個是省領導人,由於不一樣企業對應不一樣訪問者有不一樣的宴請方案,因此這裏訪問企業是須要調用對應企業的宴請方式。
省領導人訪問企業時,須要調用企業對省領導人的宴請方案,爲entertainProvincialLeader()
/** * 省領導訪問 */ class ProvincialLeaderVistor implements Vistor { @Override public void visit(AlibabaCompany alibabaCompany) { System.out.println(alibabaCompany.entertainProvincialLeader()); } @Override public void visit(TencentCompany tencentCompany) { System.out.println(tencentCompany.entertainProvincialLeader()); } }
郭嘉領導人訪問企業時,須要調用企業對郭嘉領導人的宴請方案,爲entertainNationalLeader()
/** * 郭嘉領導訪問 */ class NationalLeaderVistor implements Vistor { @Override public void visit(AlibabaCompany alibabaCompany) { System.out.println(alibabaCompany.entertainNationalLeader()); } @Override public void visit(TencentCompany tencentCompany) { System.out.println(tencentCompany.entertainNationalLeader()); } }
上面是訪問者和被訪問者的代碼,由於企業是在喜來登酒店宴請領導人,因此這裏還須要一個酒店,酒店裏面有企業合做的名單,以及負責宴請各路領導的方法提供。
/** * 酒店 */ class Hotel { private List<Company> companies = new ArrayList<>(); public void entertain(Vistor vistor) { for (Company company : companies) { company.accept(vistor); } } public void add(Company company) { companies.add(company); } }
下面提供測試代碼,看看運行的結果怎樣。
public class VisitorTest { public static void main(String[] args) { AlibabaCompany alibabaCompany = new AlibabaCompany(); TencentCompany tencentCompany = new TencentCompany(); ProvincialLeaderVistor provincialLeaderVistor = new ProvincialLeaderVistor(); NationalLeaderVistor nationalLeaderVistor = new NationalLeaderVistor(); Hotel xilaideng = new Hotel(); xilaideng.add(alibabaCompany); xilaideng.add(tencentCompany); xilaideng.entertain(provincialLeaderVistor); xilaideng.entertain(nationalLeaderVistor); } } 打印結果: Alibaba 接待省領導:十菜一湯 Tencent 接待省領導:八菜一湯 Alibaba 接待郭嘉領導:十四菜兩湯 Tencent 接待郭嘉領導:十六菜兩湯
完整的訪問者模式代碼已經呈現,花 1 分鐘思考一番,理解整個代碼後咱們來看看下面的總結。
訪問者模式有比較好的擴展性,看看訪問者代碼,咱們若是要新增一個訪問者:市領導人,只需新增市領導人類,而後企業提供招待市領導人的菜式,即可實現。固然也有它很差的地方,就是把被訪問者暴露給訪問者,使得訪問者能夠直接瞭解被訪問者的全部東西。明白了優缺點,才能更好的在實際中運用,通常訪問者模式運用於要求遍歷多個不一樣的對象的場景。
推薦閱讀
設計模式系列文章持續更新中,歡迎關注公衆號 LieBrother,一塊兒交流學習。