舉例講解設(shè)計(jì)模式中的訪問者模式在Java編程中的運(yùn)用
訪問者(Visitor)模式:封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作,它可以在不改變這個(gè)數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。訪問者模式的結(jié)構(gòu)圖如下:

通過上圖可以看到他有如下角色:
抽象訪問者(Visitor)角色:定義接口,聲明一個(gè)或多個(gè)訪問操作。
具體訪問者(ConcreteVisitor)角色:實(shí)現(xiàn)抽象訪問者所聲明的接口,也就是抽象訪問者所聲明的各個(gè)訪問操作。
抽象元素(Visitable)角色:聲明一個(gè)接受操作,接受一個(gè)訪問者對(duì)象作為一個(gè)參數(shù)。
具體元素結(jié)點(diǎn)(ConcreteElement)角色:實(shí)現(xiàn)抽象結(jié)點(diǎn)所規(guī)定的接受操作。
數(shù)據(jù)結(jié)構(gòu)對(duì)象(ObjectStructure)角色:可以遍歷結(jié)構(gòu)中的所有元素,提供一個(gè)接口讓訪問者對(duì)象都可以訪問每一個(gè)元素。
模擬代碼如下:
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一個(gè)對(duì)象生成器
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 {
/*
* 首先在客戶端先獲得一個(gè)具體的訪問者角色 遍歷對(duì)象結(jié)構(gòu) 對(duì)每一個(gè)元素調(diào)用accept方法,將具體訪問者角色傳入 這樣就完成了整個(gè)過程
*/
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("---------------");
/*
* 一個(gè)新的訪問行為 :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、一個(gè)對(duì)象結(jié)構(gòu)包含很多類對(duì)象,它們有不同的接口,而你想對(duì)這些對(duì)象實(shí)施一些依賴于其具體類的操作。
2、需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對(duì)象的類。Visitor使得你可以將相關(guān)的操作集中起來定義在一個(gè)類中。
3、當(dāng)該對(duì)象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用Visitor模式讓每個(gè)應(yīng)用僅包含需要用到的操作。
4、 定義對(duì)象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對(duì)象結(jié)構(gòu)類需要重定義對(duì)所有訪問者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。
這些個(gè)人看來都是建議,項(xiàng)目中還要具體問題具體分析了。
相關(guān)文章
java設(shè)計(jì)模式之建造者模式學(xué)習(xí)
建造者模式(Builder Pattern)主要用于“分步驟構(gòu)建一個(gè)復(fù)雜的對(duì)象”,在這其中“分步驟”是一個(gè)穩(wěn)定的算法,下面給出了詳細(xì)的示例2014-01-01
使用jvisualvm配合Visual GC插件監(jiān)控Java程序詳細(xì)總結(jié)
本節(jié)將會(huì)介紹一下jvisualvm的特性及作用、各個(gè)功能是如何使用的、最后會(huì)介紹jvisualvm的插件Visual GC的安裝及使用2021-09-09
實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之設(shè)置微服務(wù)搭建醫(yī)院模塊
這篇文章主要為大家介紹了實(shí)戰(zhàn)分布式醫(yī)療掛號(hào)系統(tǒng)之搭建醫(yī)院設(shè)置微服務(wù)模塊,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
SpringMVC中利用@InitBinder來對(duì)頁面數(shù)據(jù)進(jìn)行解析綁定的方法
本篇文章主要介紹了SpringMVC中利用@InitBinder來對(duì)頁面數(shù)據(jù)進(jìn)行解析綁定的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-03-03
SpringBoot項(xiàng)目War包部署無法注冊到Nacos中的解決
這篇文章主要介紹了SpringBoot項(xiàng)目War包部署無法注冊到Nacos中的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringCloud2020整合Nacos-Bootstrap配置不生效的解決
這篇文章主要介紹了SpringCloud2020整合Nacos-Bootstrap配置不生效的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

