<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 262,  comments - 221,  trackbacks - 0
    一、Visitor模式定義:

    作用于某個(gè)對(duì)象群中各個(gè)對(duì)象的操作. 它可以使你在不改變這些對(duì)象本身的情況下,定義作用于這些對(duì)象的新操作.在Java中,Visitor模式實(shí)際上是分離了collection結(jié)構(gòu)中的元素和對(duì)這些元素進(jìn)行操作的行為.

    二、Visitor模式構(gòu)成:

    Visitor模式由被訪問者(Visitable)和訪問者(Visitor)構(gòu)成,兩者之間是互動(dòng)的關(guān)系,即雙方必須提供接口供彼此訪問。下面是Visitor模式的一個(gè)例子(參考自www.jdon.com)

    ·被訪問者接口
    public interface Visitable {

       
    public void accept(Visitor visitor);
    }


    ·被訪問者接口實(shí)現(xiàn)類

    public class StringElement implements Visitable {
       
    private String value;

       
    public StringElement(String string) {
          value 
    = string;
       }


       
    public String getValue(){
          
    return value;
       }


       
    // 定義accept的具體內(nèi)容 這里是很簡(jiǎn)單的一句調(diào)用
       public void accept(Visitor visitor) {
          visitor.visitString(
    this);  // 被訪問者接受了一個(gè)訪問者,把自己作為回調(diào)方法中的參數(shù)
       }

    }

    ·訪問者接口
    public interface Visitor {
       
    public void visitString(StringElement stringE);
       
    public void visitFloat(FloatElement floatE);     
       
    public void visitCollection(Collection collection); 
    }


    注:因?yàn)檫@里被訪問對(duì)象的類型已經(jīng)明確,所以方法的形參定義可以具體到接口實(shí)現(xiàn)類,而不需要用接口類型

    ·訪問者接口實(shí)現(xiàn)類
    public class ConcreteVisitor implements Visitor {
       
    // 在本方法中,我們實(shí)現(xiàn)了對(duì)Collection的元素的成功訪問
       public void visitCollection(Collection collection) {
          Iterator iterator 
    = collection.iterator()
          
    while (iterator.hasNext()) {
             Object o 
    = iterator.next();
             
    if (o instanceof Visitable)       
                ((Visitable)o).accept(
    this);
          }
     
       }


       
    public void visitString(StringElement stringE) {
          System.out.println(
    "'"+stringE.getValue()+"'");
       }
     

       
    public void visitFloat(FloatElement floatE){
          System.out.println(floatE.getValue().toString()
    +"f");
       }
     
    }

    ·客戶端調(diào)用代碼
    Visitor visitor = new ConcreteVisitor();

    StringElement stringE 
    = new StringElement("I am a String");
    visitor.visitString(stringE);

    Collection list 
    = new ArrayList();
    list.add(
    new StringElement("I am a String1")); 
    list.add(
    new StringElement("I am a String2")); 
    list.add(
    new FloatElement(new Float(12))); 
    list.add(
    new StringElement("I am a String3")); 
    visitor.visitCollection(list);

    作為Visitor模式中的被訪問者,通常都需要定義一個(gè)setXxx和getXxx方法,為訪問者訪問時(shí)提供接口。或者像上例一樣,采用Call-back機(jī)制。而訪問者也需要提供相應(yīng)的接口來接收被訪問者,以輸出其內(nèi)容。

    三、Visitor模式的優(yōu)缺點(diǎn)

    從這個(gè)例子就可以看出Visitor模式的一個(gè)缺點(diǎn):對(duì)于集合中的所有類型元素,訪問者必須窮舉所有的可能方法,一旦元素的類型比較多,則訪問者的類將顯得比較龐大。

    StringElement只是一個(gè)實(shí)現(xiàn),可以拓展為更多的實(shí)現(xiàn),整個(gè)核心奧妙在accept方法中,在遍歷Collection時(shí),通過相應(yīng)的accept方法調(diào)用具體類型的被訪問者。這一步確定了被訪問者類型。

    Visitor模式的一個(gè)優(yōu)點(diǎn)體現(xiàn)在對(duì)集合元素的訪問中:由于集合中的可訪問元素都實(shí)現(xiàn)了Visitable接口,所以在迭代集合的過程中,我們可以將每個(gè)元素都看成是接口類型。
     
    其次由于JAVA語言的多態(tài)性,雖然每個(gè)元素都是接口類型(Visitable),但每個(gè)元素的實(shí)現(xiàn)類不同,所以在調(diào)用accept方法時(shí),虛擬機(jī)“知道”應(yīng)該調(diào)起那個(gè)正確的方法(例如:集合中的一個(gè)String元素,會(huì)調(diào)用StringElement的accept方法)

    Visitor對(duì)集合類型的訪問過程:對(duì)集合進(jìn)行迭代,將自身作為參數(shù)調(diào)用每個(gè)被訪問者的accept方法,被訪問者的accept方法也以自身為參數(shù)回調(diào)訪問者的visitXxx方法。

    四、Visitor模式的使用前提和注意點(diǎn)

    使用訪問者模式前提是對(duì)象群結(jié)構(gòu)中(Collection) 中的對(duì)象類型很少改變。

    在兩個(gè)接口Visitor和Visitable中,確保Visitable很少變化,也就是說,確保不能老有新的Element元素類型加進(jìn)來,可以變化的是訪問者行為或操作,也就是Visitor的不同子類可以有多種,這樣使用訪問者模式最方便.

    如果對(duì)象集合中的對(duì)象集合經(jīng)常有變化, 那么不但Visitor實(shí)現(xiàn)要變化,Visistable也要增加相應(yīng)行為,GOF建議是,不如在這些對(duì)象類中直接逐個(gè)定義操作,無需使用訪問者設(shè)計(jì)模式。

    --摘自www.jdon.com的《Visitor模式》 一節(jié)

    原因:

    如果Visitable中元素的類型是固定的或者很少變化的,那么即使Visitor中相應(yīng)的訪問行為發(fā)生改變了,對(duì)Visitable也沒有影響。相反如果Visitable中元素的類型變化頻繁,除了Visitable要增加新的類型,Visitor也要增加相應(yīng)的visitXxx方法。所以說使用Visitor模式的一個(gè)前提是被訪問者的類型很少改變



    -------------------------------------------------------------
    生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
    posted on 2008-04-15 17:38 Paul Lin 閱讀(4477) 評(píng)論(2)  編輯  收藏 所屬分類: 模式與重構(gòu)


    FeedBack:
    # re: 設(shè)計(jì)模式總結(jié)-Visitor模式
    2008-05-11 16:04 | 無羽蒼鷹
    ^^學(xué)習(xí)了  回復(fù)  更多評(píng)論
      
    # re: 設(shè)計(jì)模式總結(jié)-Visitor模式
    2009-03-06 13:07 | rrroger
    jdon這篇文章也太老了,visitor的優(yōu)缺點(diǎn)分析的都太淺薄,參考價(jià)值不大  回復(fù)  更多評(píng)論
      
    <2008年4月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點(diǎn)博客

    好友博客

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 国产精品亚洲片夜色在线| 无人在线观看免费高清视频 | 在线a亚洲v天堂网2019无码| 免费a在线观看播放| 免费又黄又爽又猛的毛片| 免费大黄网站在线观| 亚洲男人第一无码aⅴ网站| 亚洲综合久久夜AV | 成人午夜亚洲精品无码网站| 337p日本欧洲亚洲大胆裸体艺术| 亚洲国产精品成人久久| 亚洲小视频在线观看| 精品日韩亚洲AV无码一区二区三区| 亚洲最大的成网4438| 亚洲香蕉久久一区二区三区四区| 国产精品亚洲综合久久| 亚洲av日韩av永久无码电影| 黄色网页免费观看| jizz免费在线影视观看网站| 曰批全过程免费视频在线观看无码 | 国产免费卡一卡三卡乱码| 免费大黄网站在线观| 久久精品亚洲乱码伦伦中文| 国产精品亚洲精品日韩已满| 亚洲黄色在线观看视频| 国产成人亚洲合集青青草原精品| 亚洲aⅴ无码专区在线观看| 亚洲精品偷拍视频免费观看| 免费国产成人午夜在线观看| 人妻视频一区二区三区免费| 国产人成免费视频| 亚洲高清国产拍精品26U| 亚洲另类自拍丝袜第1页| 香蕉视频亚洲一级| 国产午夜精品久久久久免费视| 国色精品卡一卡2卡3卡4卡免费| 日韩免费观看的一级毛片| 国产精品亚洲产品一区二区三区| 亚洲国产综合91精品麻豆| 国产成人亚洲精品| 久久国产精品免费一区|