国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

深入淺出Java的訪問者模式

瀏覽:3日期:2024-06-30 10:33:44
內(nèi)容: 一、引子 對(duì)于系統(tǒng)中一個(gè)已經(jīng)完成的類層次結(jié)構(gòu),我們已經(jīng)給它提供了滿足需求的接口。但是面對(duì)新增加的需求,我們應(yīng)該怎么做呢?如果這是為數(shù)不多的幾次變動(dòng),而且你不用為了一個(gè)需求的調(diào)整而將整個(gè)類層次結(jié)構(gòu)統(tǒng)統(tǒng)地修改一遍,那么直接在原有類層次結(jié)構(gòu)上修改也許是個(gè) 不錯(cuò) 的主意。 但是往往我們遇到的卻是:這樣的需求變動(dòng)也許會(huì)不停的發(fā)生;更重要的是需求的任何變動(dòng)可能都要讓你將整個(gè)類層次結(jié)構(gòu)修改個(gè)底朝天……。這種類似的操作分布在不同的類里面,不是一個(gè)好現(xiàn)象,我們要對(duì)這個(gè)結(jié)構(gòu)重構(gòu)一下了。 那么,訪問者模式也許是你很好的選擇。 二、定義與結(jié)構(gòu) 訪問者模式,顧名思義使用了這個(gè)模式后就可以在不修改已有程序結(jié)構(gòu)的前提下,通過添加額外的“訪問者來完成對(duì)已有代碼功能的提升。 《設(shè)計(jì)模式》一書對(duì)于訪問者模式給出的定義為:表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。從定義可以看出結(jié)構(gòu)對(duì)象是使用訪問者模式必須條件,而且這個(gè)結(jié)構(gòu)對(duì)象必須存在遍歷自身各個(gè)對(duì)象的方法。這便類似于java中的collection概念了。 以下是訪問者模式的組成結(jié)構(gòu): 1) 訪問者角色(Visitor):為該對(duì)象結(jié)構(gòu)中具體元素角色聲明一個(gè)訪問操作接口。該操作接口的名字和參數(shù)標(biāo)識(shí)了發(fā)送訪問請(qǐng)求給具體訪問者的具體元素角色。這樣訪問者就可以通過該元素角色的特定接口直接訪問它。 2) 具體訪問者角色(Concrete Visitor):實(shí)現(xiàn)每個(gè)由訪問者角色(Visitor)聲明的操作。 3) 元素角色(Element):定義一個(gè)Accept操作,它以一個(gè)訪問者為參數(shù)。 4) 具體元素角色(Concrete Element):實(shí)現(xiàn)由元素角色提供的Accept操作。 5) 對(duì)象結(jié)構(gòu)角色(Object Structure):這是使用訪問者模式必備的角色。它要具備以下特征:能枚舉它的元素;可以提供一個(gè)高層的接口以允許該訪問者訪問它的元素;可以是一個(gè)復(fù)合(組合模式)或是一個(gè)集合,如一個(gè)列表或一個(gè)無序集合。 來張類圖就能更加清晰的看清訪問者模式的結(jié)構(gòu)了。那么像引言中假想的。我們應(yīng)該做些什么才能讓訪問者模式跑起來呢?首先我們要在原有的類層次結(jié)構(gòu)中添加accept方法。然后將這個(gè)類層次中的類放到一個(gè)對(duì)象結(jié)構(gòu)中去。這樣再去創(chuàng)建訪問者角色…… 三、舉例 本人閱歷實(shí)在可憐,沒能找到訪問者模式在實(shí)際應(yīng)用中的例子。只好借《Thinking in Patterns with java》中的教學(xué)代碼一用。我稍微做了下修改。 import java.util.*; import junit.framework.*; //訪問者角色 interface Visitor {  void visit(Gladiolus g);  void visit(Runuculus r);  void visit(Chrysanthemum c); } // The Flower hierarchy cannot be changed: //元素角色 interface Flower {  void accept(Visitor v); } //以下三個(gè)具體元素角色 class Gladiolus implements Flower {  public void accept(Visitor v) { v.visit(this);} } class Runuculus implements Flower {  public void accept(Visitor v) { v.visit(this);} } class Chrysanthemum implements Flower {  public void accept(Visitor v) { v.visit(this);} } // Add the ability to produce a string: //實(shí)現(xiàn)的具體訪問者角色 class StringVal implements Visitor {  String s;  public String toString() { return s; }  public void visit(Gladiolus g) { s = 'Gladiolus';  }  public void visit(Runuculus r) { s = 'Runuculus';  }  public void visit(Chrysanthemum c) { s = 'Chrysanthemum';  } } // Add the ability to do 'Bee' activities: //另一個(gè)具體訪問者角色 class Bee implements Visitor {  public void visit(Gladiolus g) { System.out.println('Bee and Gladiolus');  }  public void visit(Runuculus r) { System.out.println('Bee and Runuculus');  }  public void visit(Chrysanthemum c) { System.out.println('Bee and Chrysanthemum');  } } //這是一個(gè)對(duì)象生成器 //這不是一個(gè)完整的對(duì)象結(jié)構(gòu),這里僅僅是模擬對(duì)象結(jié)構(gòu)中的元素 class FlowerGenerator {  private static Random rand = new Random();  public static Flower newFlower() { switch (rand.nextInt(3)) { default:  case 0: return new Gladiolus();   case 1: return new Runuculus();  case 2: return new Chrysanthemum(); }  } } //客戶 測(cè)試程序 public class BeeAndFlowers extends TestCase {  /* 在這里你能看到訪問者模式執(zhí)行的流程: 首先在客戶端先獲得一個(gè)具體的訪問者角色 遍歷對(duì)象結(jié)構(gòu) 對(duì)每一個(gè)元素調(diào)用accept方法,將具體訪問者角色傳入 這樣就完成了整個(gè)過程  */  //對(duì)象結(jié)構(gòu)角色在這里才 組裝 上  List flowers = new ArrayList();  public BeeAndFlowers() { for(int i = 0; i < 10; i++)  flowers.add(FlowerGenerator.newFlower());  }  Visitor sval ;  public void test() { // It’s almost as if I had a function to // produce a Flower string representation: //這個(gè)地方你可以修改以便使用另外一個(gè)具體訪問者角色 sval = new StringVal(); Iterator it = flowers.iterator(); while(it.hasNext()) {  ((Flower)it.next()).accept(sval);  System.out.println(sval); }  }  public static void main(String args[]) { junit.textui.TestRunner.run(BeeAndFlowers.class);  } } 四、雙重分派 對(duì)了,你在上面的例子中體會(huì)到雙重分派的實(shí)現(xiàn)了沒有? 首先在客戶程序中將具體訪問者模式作為參數(shù)傳遞給具體元素角色(加亮的地方所示)。這便完成了一次分派。 進(jìn)入具體元素角色后,具體元素角 色調(diào) 用作為參數(shù)的具體訪問者模式中的visitor方法,同時(shí)將自己(this)作為參數(shù)傳遞進(jìn)去。具體訪問者模式再根據(jù)參數(shù)的不同來選擇方法來執(zhí)行(加亮的地方所示)。這便完成了第二次分派。 五、優(yōu)缺點(diǎn)及適用情況 先來看下訪問者模式的使用能否避免引言中的痛苦。使用了訪問者模式以后,對(duì)于原來的類層次增加新的操作,僅僅需要實(shí)現(xiàn)一個(gè)具體訪問者角色就可以了,而不必修改整個(gè)類層次。而且這樣符合“開閉原則的要求。而且每個(gè)具體的訪問者角色都對(duì)應(yīng)于一個(gè)相關(guān)操作,因此如果一個(gè)操作的需求有變,那么僅僅修改一個(gè)具體訪問者角色,而不用改動(dòng)整個(gè)類層次。 看來訪問者模式確實(shí)能夠解決我們面臨的一些問題。 而且由于訪問者模式為我們的系統(tǒng)多提供了一層“訪問者,因此我們可以在訪問者中添加一些對(duì)元素角色的額外操作。 但是“開閉原則的遵循總是片面的。如果系統(tǒng)中的類層次發(fā)生了變化,會(huì)對(duì)訪問者模式產(chǎn)生什么樣的影響呢?你必須修改訪問者角色和每一個(gè)具體訪問者角色…… 看來訪問者角色不適合具體元素角色經(jīng)常發(fā)生變化的情況。而且訪問者角色要執(zhí)行與元素角色相關(guān)的操作,就必須讓元素角色將自己內(nèi)部屬性暴露出來,而在java中就意味著其它的對(duì)象也可以訪問。這就破壞了元素角色的封裝性。而且在訪問者模式中,元素與訪問者之間能夠傳遞的信息有限,這往往也會(huì)限制訪問者模式的使用。 《設(shè)計(jì)模式》一書中給出了訪問者模式適用的情況: 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)常改變,那么可能還是在這些類中定義這些操作較好。 你是否能很好的理解呢? 六、總結(jié) 這是一個(gè)巧妙而且復(fù)雜的模式,它的使用條件比較苛刻。當(dāng)系統(tǒng)中存在著固定的數(shù)據(jù)結(jié)構(gòu)(比如上面的類層次),而有著不同的行為,那么訪問者模式也許是個(gè)不錯(cuò)的選擇。 Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 日韩美视频网站 | 欧美成人免费一级人片 | 亚洲一区二区三区四区在线 | 三级黄色在线播放 | 寡妇一级a毛片免费播放 | 国产一区亚洲二区三区毛片 | 黄a 大片a v 永久免费 | 免费一级片网站 | 欧美一级高清片欧美国产欧美 | 性做久久久久久久免费看 | 国产精品久久久久久久hd | 男女视频免费 | 久久午夜网 | 久久福利青草免费精品 | 性色午夜视频免费男人的天堂 | 成人性动漫高清免费观看网址 | 国内美女福利视频在线观看网站 | av狼论坛 | 久久一本综合 | 成人免费网站视频www | 一区高清 | 99热com| 毛片韩国| 成人午夜爽爽爽免费视频 | 国产一级毛片午夜 | 久久久久综合给合狠狠狠 | 精品国产呦系列在线看 | 99久久精品国产一区二区小说 | 亚洲成人18| 国产一级片网址 | 日韩一区二区三区在线播放 | 中文字幕在线视频网 | 国产精品免费aⅴ片在线观看 | 18在线网站 | 日韩精品另类天天更新影院 | 国产永久高清免费动作片www | 日韩欧美中文字幕一区二区三区 | 成人午夜两性视频免费看 | 日韩精品免费视频 | 老色歌uuu26 老师张开腿让我爽了一夜视频 | 波多野结衣一区二区三区高清在线 |