設計模式之Visitor

Visitor 定義
作用於某個物件群中各個物件的操作。 它可以使你在不改變這些物件本身的情況下 , 定義作用於這些物件的新操作。

Java,Visitor 模式實際上是分離了 collection 結構中的元素和對這些元素進行操作的行爲。

爲何使用 Visitor?
Java
Collection( 包括 VectorHashtable) 是我們最經常使用的技術 , 可是 Collection 好象是個黑色大染缸 , 本來有各種鮮明類型特徵的物件一旦放入後 , 再取出時 , 這些類型就消失了。那麽我們勢必要用 If 來判斷 ,:


Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
  
Object o = iterator.next();
  
if (o instanceof Collection)
     
messyPrintCollection((Collection)o);
  
else if (o instanceof String)
     
System.out.println("'"+o.toString()+"'");
  
else if (o instanceof Float)
     
System.out.println(o.toString()+"f");
  
else
     
System.out.println(o.toString());
}
在上例中 , 我們使用了 instanceof 來判斷 o 的類型。

很顯然 , 這樣做的缺點代碼 If else if 很繁瑣。我們就可以使用 Visitor 模式解決它。

如何使用 Visitor?
針對上例 , 我們設計一個介面 visitor 訪問者 :

public interface Visitor
{
  
public void visitCollection(Collection collection);
  
public void visitString(String string);
   public void visitFloat(Float float);
}

在這個介面中 , 將我們認爲 Collection 有可能的類別的類型放入其中。

有了訪問者 , 我們需要被訪問者 , 被訪問者就是我們 Collection 的每個元素 Element, 我們要爲這些 Element 定義一個可以接受訪問的介面 ( 訪問和被訪問是互動的 , 只有訪問者 , 被訪問者如果表示不歡迎 , 訪問者就不能訪問 ),

我們定義這個介面叫 Visitable, 用來定義一個 Accept 操作 , 也就是說讓 Collection 每個元素具備可訪問性。

public interface Visitable
{
   public void accept(Visitor visitor);
}

好了 , 有了兩個介面 , 我們就要定義他們的具體實現 (Concrete class):

public class ConcreteElement implements Visitable
{
  
private String value;
  
public ConcreteElement(String string) {
     
value = string;
  
}
   // 定義 accept 的具體內容 這裏是很簡單的一句呼叫
  
public void accept(Visitor visitor) {
     
visitor.visitString(this);
   }
}

再看看訪問者的 Concrete 實現 :

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(String string) {
     
System.out.println("'"+string+"'");
   }

   public void visitFloat(Float float) {
     
System.out.println(float.toString()+"f");
   }
}

?

在上面的 visitCollection 我們實現了對 Collection 每個元素訪問 , 只使用了一個判斷語句 , 只要判斷其是否可以訪問。

至此 , 我們完成了 Visitor 模式基本架構。

使用 Visitor 模式的前提
物件群結構中 (Collection) 中的物件類型很少改變 , 也就是說訪問者的身份類型很少改變 , 如上面中 Visitor 中的類型很少改變 , 如果需要增加新的操作 , 比如上例中我們在 ConcreteElement 具體實現外 , 還需要新的 ConcreteElement2 ConcreteElement3

可見使用 Visitor 模式是有前提的 , 在兩個介面 VisitorVisitable, 確保 Visitor 很少變化 , 變化的是 Visitable, 這樣使用 Visitor 最方便。

如果 Visitor 也經常變化 , 也就是說 , 物件群中的物件類型經常改變 , 一般建議是 , 不如在這些物件類別中逐個定義操作。但是 JavaReflect 技術解決了這個問題。

Reflect 技術是在運行期間動態獲取物件類型和方法的一種技術 ,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值