舉例講解設(shè)計模式中的訪問者模式在Java編程中的運用
訪問者(Visitor)模式:封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作,它可以在不改變這個數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。訪問者模式的結(jié)構(gòu)圖如下:
通過上圖可以看到他有如下角色:
抽象訪問者(Visitor)角色:定義接口,聲明一個或多個訪問操作。
具體訪問者(ConcreteVisitor)角色:實現(xiàn)抽象訪問者所聲明的接口,也就是抽象訪問者所聲明的各個訪問操作。
抽象元素(Visitable)角色:聲明一個接受操作,接受一個訪問者對象作為一個參數(shù)。
具體元素結(jié)點(ConcreteElement)角色:實現(xiàn)抽象結(jié)點所規(guī)定的接受操作。
數(shù)據(jù)結(jié)構(gòu)對象(ObjectStructure)角色:可以遍歷結(jié)構(gòu)中的所有元素,提供一個接口讓訪問者對象都可以訪問每一個元素。
模擬代碼如下:
interface Visitor { void visit(Gladiolus g); void visit(Chrysanthemum c); }
// concrete visitor 名稱訪問 class StringVisitor implements Visitor { String s; public String toString() { return s; } public void visit(Gladiolus g) { s = "Gladiolus"; } public void visit(Chrysanthemum c) { s = "Chrysanthemum"; } }
// concrete visitor 蜜蜂訪問 class BeeVisitor implements Visitor { public void visit(Gladiolus g) { System.out.println("蜜蜂 來 訪問 Gladiolus"); } public void visit(Chrysanthemum c) { System.out.println("蜜蜂 來 訪問 Chrysanthemum"); } }
interface Flower { void accept(Visitor v); }
/* * concrete element 菊花 */ class Chrysanthemum implements Flower { public void accept(Visitor v) { v.visit(this); } }
// concrete element 劍蘭 class Gladiolus implements Flower { public void accept(Visitor v) { v.visit(this); } }
//這是Flower一個對象生成器 class FlowerGenerator { private static Random rand = new Random(); public static Flower newFlower() { switch (rand.nextInt(2)) { default: case 0: return new Gladiolus(); case 1: return new Chrysanthemum(); } } }
public class Test { /* * 首先在客戶端先獲得一個具體的訪問者角色 遍歷對象結(jié)構(gòu) 對每一個元素調(diào)用accept方法,將具體訪問者角色傳入 這樣就完成了整個過程 */ public static void main(String args[]) { List<Flower> flowers = new ArrayList<Flower>(); for (int i = 0; i < 10; i++) flowers.add(FlowerGenerator.newFlower()); Visitor visitor = new StringVisitor(); Iterator<Flower> iterator = flowers.iterator(); while (iterator.hasNext()) { iterator.next().accept(visitor); System.out.println(visitor); } System.out.println("---------------"); /* * 一個新的訪問行為 :BeeVisitor 蜜蜂訪問 */ Visitor visitor2 = new BeeVisitor(); for (Flower flower : flowers) { flower.accept(visitor2); } } }
結(jié)果:
Gladiolus Chrysanthemum Chrysanthemum Gladiolus Chrysanthemum Chrysanthemum Chrysanthemum Chrysanthemum Gladiolus Gladiolus --------------- 蜜蜂 來 訪問 Gladiolus 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Gladiolus 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Chrysanthemum 蜜蜂 來 訪問 Gladiolus 蜜蜂 來 訪問 Gladiolus
有以下情形可以考慮使用訪問者模式:
1、一個對象結(jié)構(gòu)包含很多類對象,它們有不同的接口,而你想對這些對象實施一些依賴于其具體類的操作。
2、需要對一個對象結(jié)構(gòu)中的對象進行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對象的類。Visitor使得你可以將相關(guān)的操作集中起來定義在一個類中。
3、當(dāng)該對象結(jié)構(gòu)被很多應(yīng)用共享時,用Visitor模式讓每個應(yīng)用僅包含需要用到的操作。
4、 定義對象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對象結(jié)構(gòu)類需要重定義對所有訪問者的接口,這可能需要很大的代價。如果對象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。
這些個人看來都是建議,項目中還要具體問題具體分析了。
相關(guān)文章
java設(shè)計模式之建造者模式學(xué)習(xí)
建造者模式(Builder Pattern)主要用于“分步驟構(gòu)建一個復(fù)雜的對象”,在這其中“分步驟”是一個穩(wěn)定的算法,下面給出了詳細(xì)的示例2014-01-01使用jvisualvm配合Visual GC插件監(jiān)控Java程序詳細(xì)總結(jié)
本節(jié)將會介紹一下jvisualvm的特性及作用、各個功能是如何使用的、最后會介紹jvisualvm的插件Visual GC的安裝及使用2021-09-09實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)之設(shè)置微服務(wù)搭建醫(yī)院模塊
這篇文章主要為大家介紹了實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)之搭建醫(yī)院設(shè)置微服務(wù)模塊,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04SpringMVC中利用@InitBinder來對頁面數(shù)據(jù)進行解析綁定的方法
本篇文章主要介紹了SpringMVC中利用@InitBinder來對頁面數(shù)據(jù)進行解析綁定的方法,非常具有實用價值,需要的朋友可以參考下2018-03-03SpringBoot項目War包部署無法注冊到Nacos中的解決
這篇文章主要介紹了SpringBoot項目War包部署無法注冊到Nacos中的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01SpringCloud2020整合Nacos-Bootstrap配置不生效的解決
這篇文章主要介紹了SpringCloud2020整合Nacos-Bootstrap配置不生效的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01