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

          作用于某個對象群中各個對象的操作. 它可以使你在不改變這些對象本身的情況下,定義作用于這些對象的新操作.在Java中,Visitor模式實際上是分離了collection結構中的元素和對這些元素進行操作的行為.

          二、Visitor模式構成:

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

          ·被訪問者接口
          public interface Visitable {

             
          public void accept(Visitor visitor);
          }


          ·被訪問者接口實現類

          public class StringElement implements Visitable {
             
          private String value;

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


             
          public String getValue(){
                
          return value;
             }


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

          }

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


          注:因為這里被訪問對象的類型已經明確,所以方法的形參定義可以具體到接口實現類,而不需要用接口類型

          ·訪問者接口實現類
          public class ConcreteVisitor implements Visitor {
             
          // 在本方法中,我們實現了對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");
             }
           
          }

          ·客戶端調用代碼
          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模式中的被訪問者,通常都需要定義一個setXxx和getXxx方法,為訪問者訪問時提供接口。或者像上例一樣,采用Call-back機制。而訪問者也需要提供相應的接口來接收被訪問者,以輸出其內容。

          三、Visitor模式的優缺點

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

          StringElement只是一個實現,可以拓展為更多的實現,整個核心奧妙在accept方法中,在遍歷Collection時,通過相應的accept方法調用具體類型的被訪問者。這一步確定了被訪問者類型。

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

          Visitor對集合類型的訪問過程:對集合進行迭代,將自身作為參數調用每個被訪問者的accept方法,被訪問者的accept方法也以自身為參數回調訪問者的visitXxx方法。

          四、Visitor模式的使用前提和注意點

          使用訪問者模式前提是對象群結構中(Collection) 中的對象類型很少改變。

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

          如果對象集合中的對象集合經常有變化, 那么不但Visitor實現要變化,Visistable也要增加相應行為,GOF建議是,不如在這些對象類中直接逐個定義操作,無需使用訪問者設計模式。

          --摘自www.jdon.com的《Visitor模式》 一節

          原因:

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



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


          FeedBack:
          # re: 設計模式總結-Visitor模式
          2008-05-11 16:04 | 無羽蒼鷹
          ^^學習了  回復  更多評論
            
          # re: 設計模式總結-Visitor模式
          2009-03-06 13:07 | rrroger
          jdon這篇文章也太老了,visitor的優缺點分析的都太淺薄,參考價值不大  回復  更多評論
            
          <2008年4月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 屯门区| 绥宁县| 岑巩县| 密山市| 招远市| 通辽市| 宣威市| 安庆市| 旬邑县| 林芝县| 新余市| 临颍县| 祁阳县| 德令哈市| 枝江市| 富民县| 延长县| 电白县| 长汀县| 克什克腾旗| 明溪县| 鄄城县| 分宜县| 扎兰屯市| 郎溪县| 东阳市| 长岭县| 桐乡市| 铁岭市| 安西县| 随州市| 洞头县| 隆子县| 高青县| 巴青县| 尤溪县| 项城市| 中超| 穆棱市| 湘乡市| 平昌县|