舉例講解設(shè)計(jì)模式中的訪問(wèn)者模式在Java編程中的運(yùn)用
訪問(wèn)者(Visitor)模式:封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作,它可以在不改變這個(gè)數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。訪問(wèn)者模式的結(jié)構(gòu)圖如下:
通過(guò)上圖可以看到他有如下角色:
抽象訪問(wèn)者(Visitor)角色:定義接口,聲明一個(gè)或多個(gè)訪問(wèn)操作。
具體訪問(wèn)者(ConcreteVisitor)角色:實(shí)現(xiàn)抽象訪問(wèn)者所聲明的接口,也就是抽象訪問(wèn)者所聲明的各個(gè)訪問(wèn)操作。
抽象元素(Visitable)角色:聲明一個(gè)接受操作,接受一個(gè)訪問(wèn)者對(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è)接口讓訪問(wèn)者對(duì)象都可以訪問(wèn)每一個(gè)元素。
模擬代碼如下:
interface Visitor { void visit(Gladiolus g); void visit(Chrysanthemum c); }
// concrete visitor 名稱訪問(wèn) 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 蜜蜂訪問(wèn) class BeeVisitor implements Visitor { public void visit(Gladiolus g) { System.out.println("蜜蜂 來(lái) 訪問(wèn) Gladiolus"); } public void visit(Chrysanthemum c) { System.out.println("蜜蜂 來(lái) 訪問(wèn) 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è)具體的訪問(wèn)者角色 遍歷對(duì)象結(jié)構(gòu) 對(duì)每一個(gè)元素調(diào)用accept方法,將具體訪問(wèn)者角色傳入 這樣就完成了整個(gè)過(guò)程 */ 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è)新的訪問(wèn)行為 :BeeVisitor 蜜蜂訪問(wèn) */ Visitor visitor2 = new BeeVisitor(); for (Flower flower : flowers) { flower.accept(visitor2); } } }
結(jié)果:
Gladiolus Chrysanthemum Chrysanthemum Gladiolus Chrysanthemum Chrysanthemum Chrysanthemum Chrysanthemum Gladiolus Gladiolus --------------- 蜜蜂 來(lái) 訪問(wèn) Gladiolus 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Gladiolus 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Chrysanthemum 蜜蜂 來(lái) 訪問(wèn) Gladiolus 蜜蜂 來(lái) 訪問(wèn) Gladiolus
有以下情形可以考慮使用訪問(wèn)者模式:
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)的操作集中起來(lái)定義在一個(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ì)所有訪問(wèn)者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。
這些個(gè)人看來(lái)都是建議,項(xiàng)目中還要具體問(wèn)題具體分析了。
欄 目:Java編程
本文標(biāo)題:舉例講解設(shè)計(jì)模式中的訪問(wèn)者模式在Java編程中的運(yùn)用
本文地址:http://mengdiqiu.com.cn/a1/Javabiancheng/8474.html
您可能感興趣的文章


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Java咖啡館(1)——嘆咖啡
- 01-10JVM的垃圾回收機(jī)制詳解和調(diào)優(yōu)
- 01-10Java Socket編程(三) 服務(wù)器Sockets
- 01-10Java進(jìn)階:Struts多模塊的技巧
- 01-10J2SE 1.5版本的新特性一覽
- 01-10Java Socket編程(一) Socket傳輸模式
- 01-10Java運(yùn)行時(shí)多態(tài)性的實(shí)現(xiàn)
- 01-10Java Socket編程(二) Java面向連接的類
- 01-10Java Socket編程(四) 重復(fù)和并發(fā)服務(wù)
- 01-10Java經(jīng)驗(yàn)點(diǎn)滴:處理沒(méi)有被捕獲的異常
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文