訪問者模式

訪問者模式是設計模式中比較難理解的一個設計模式,理解這個模式之前,先說說開閉原則。

所謂開閉原則是指,當需求擴展變化的時候,儘量不要修改原來的類,模塊等(閉),而是進行擴展(開)。對修改閉對擴展開(Software entities should be open for extension,but closed for modification

java代碼中的一個慣例:一般在繼承的情況下會使用父類或者接口名來聲明類變量,以便有更好擴展性。


當使用父類名稱聲明變量的時候,碰上重載的情況下就會考慮出現如下情況:

重載一般是靜態綁定,即根據聲明類型綁定方法;而我們使用一般是會父類名進行聲明的,這樣就會出現問題。如下:

public class Father{
    ……
}

public class Son extends Father{
   ……
}
public class Business{
  public void play(Father f){
     System.out.println("Father is playing");
   }
   public void play(Son s){
      System.out.println("Son is playing");
   }
}


public class Test{
  public static void main(String []args){
       private Father son = new Son();
       Business bs = new Business();
       bs.play(son);
  }
  
}
如上不會如願的輸出Son is playing。而是上者。此時必須在Business類下加上類型判斷才能輸出正確的類型。即如下修改片段:

public void play(Father f){
   if(f instanceof Son){
       play((Son) f);
   }else{
      System.out.println("Father is playing");
    }
     
   }
試想,在play(Father f)方法中要進行instanceof判斷,如果類型子類多的話,會變得很難維護。


根據開閉原則,如果Father產生新的子類的情況下,會很大程度的修改Business類中的方法,這很不利於程序的維護升級。

這個時候,訪問者模式就會使用到。如下,在Father類和Son類中都增加一個方法,如下:

public void accept(Business b){

    b.play(this);

}

並且修改測試類爲:

public class Test{
  public static void main(String []args){
       private Father son = new Son();
       Business bs = new Business();
       son.accept(bs);
  }
  
}
//如果產生新子類的時候,對代碼影響也不會太大,實現此功能比較關鍵的地方在於下面的<span style="font-family: Arial, Helvetica, sans-serif;">this對象</span>
b.play(this);

這就是訪問者模式的使用



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章