訪問者模式

意圖和簡介

意圖
使一個高層級的類方便地添加新的方法/操作/接口

  • 擴(kuò)展性/表達(dá)式問題:對于任何一門編程語言而言,添加新子類與添加新方法之間是一個兩難的選擇(即若選擇使一個類易于添加新的操作那么這個類就難以去擴(kuò)展新的子類,而若這個類容易擴(kuò)展新的子類,那么就難以去添加新的操作)

何時使用
對于面向?qū)ο缶幊?,我們的依賴于抽象原則讓我們常常去擴(kuò)展一個抽象類的子類,而非它的方法。而有時我們會遇到這樣一種情況,它的子類是已經(jīng)確定的了。而它的方法/操作卻并非確定的(有很多)。
那么這個時候,我們可以使用訪問者模式將其轉(zhuǎn)換為易于擴(kuò)展新方法而非易于擴(kuò)展新子類的一個模式。
注:訪問者模式并沒有解決表達(dá)式問題,只是將問題的呈現(xiàn)變換了一種形式

使用的具體思路
????如果一個較高層級的類,它的子類是已知且確定的而操作是未知的,那么我們可以將其操作的具體實現(xiàn)從子類中抽取出來放到訪問者類中去實現(xiàn)。而它本身則通過accept方法調(diào)用訪問者類中相應(yīng)的visit()方法來實現(xiàn)將表達(dá)式問題從易于擴(kuò)展新的子類難添加新操作轉(zhuǎn)移為易于添加新操作而難以去擴(kuò)展新子類

可以拿生活中的事情做類比。
這個不知道操作有哪些種類的較高層次的類Receiver,某家的主人,這主人的種類是確定的,同時他們所擁有的房子也是確定的。有天客人Visitor去他家做客,visitor的種類并非是確定的,所以這些客人去某個主人家去說什么話做什么事也就是不知道的。而具體的客人說的具體的話和做的具體的事(即方法/操作)是根據(jù)不同的主人,該主人所擁有的房子以及這個visitor具體是誰來確定的(雙分派,即具體的操作由主客雙方來確定)。



具體示例

這里計算機(jī)對普通用戶開放的部件ComputerPart作為被訪問者(計算機(jī)對普通用戶開放的部件是確定和已知的)
具體的用戶操作作為訪問者,操作的種類這里實現(xiàn)了兩種,一種display,一種close,(展示和關(guān)閉)


1.被訪問者,抽象類ComputerPart

public interface ComputerPart
{
   public void accept(ComputerPartVisitor computerPartVisitor);
}



2.被訪問者ComputerPart的幾個具體子類

public class Keyboard implements ComputerPart
{
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor){
        computerPartVisitor.visit(this);
    }
}


public class Monitor implements ComputerPart
{
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor){
        computerPartVisitor.visit(this);
    }
}


public class Mouse  implements ComputerPart {
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

public class Computer implements ComputerPart
{
   ComputerPart[] parts;
   public Computer(){
       parts = new ComputerPart[]{
        new Mouse(),new Keyboard(),new Monitor()
        };
    }
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      for (int i = 0; i < parts.length; i++) {
         parts[i].accept(computerPartVisitor);
      }
      computerPartVisitor.visit(this);
   }
   
}

3.訪問者抽象類

public interface ComputerPartVisitor
{
    public void visit(Computer computer);
    public void visit(Mouse mouse);
    public void visit(Keyboard keyboard);
    public void visit(Monitor monitor);
}

4.兩種訪問者的具體實現(xiàn)類(分別封裝了display操作和close操作)

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
 
   @Override
   public void visit(Computer computer) {
      System.out.println("Displaying Computer.");
   }
 
   @Override
   public void visit(Mouse mouse) {
      System.out.println("Displaying Mouse.");
   }
 
   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("Displaying Keyboard.");
   }
 
   @Override
   public void visit(Monitor monitor) {
      System.out.println("Displaying Monitor.");
   }
}

public class ComputerPartCloseVisitor implements ComputerPartVisitor {
 
   @Override
   public void visit(Computer computer) {
      System.out.println("closing Computer.");
   }
 
   @Override
   public void visit(Mouse mouse) {
      System.out.println("closing Mouse.");
   }
 
   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("closing Keyboard.");
   }
 
   @Override
   public void visit(Monitor monitor) {
      System.out.println("closing Monitor.");
   }
}

5.測試類

public class VisitorPatternDemo
{
   public static void main(String[] args) {
 
      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
      ComputerPart monitor = new Monitor();
      monitor.accept(new ComputerPartDisplayVisitor());
      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartCloseVisitor());
   }
}

綜上:操作對具體的計算機(jī)部件和操作的種類(display/close)的依賴構(gòu)成了訪問者模式中的職責(zé)雙分派。這樣就得到使用訪問者模式的一個場景:在遇到需要對一個類中操作的職責(zé)進(jìn)行雙分派的時候,我們可以考慮訪問者模式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是訪問者模式 模式的結(jié)構(gòu) 典型代碼 訪問者模式中的偽動態(tài)雙分派 代碼示例 訪問者...
    w1992wishes閱讀 943評論 0 6
  • 1 場景問題# 1.1 擴(kuò)展客戶管理的功能## 考慮這樣一個應(yīng)用:擴(kuò)展客戶管理的功能。 既然是擴(kuò)展功能,那么肯定是...
    七寸知架構(gòu)閱讀 3,031評論 1 58
  • 【學(xué)習(xí)難度:★★☆☆☆,使用頻率:★★★☆☆】直接出處:訪問者模式梳理和學(xué)習(xí):https://github.com...
    BruceOuyang閱讀 1,024評論 2 2
  • 設(shè)計模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計原則時需要注意以下幾點:a) 高內(nèi)聚、低耦合和單一職能的“沖突”實際上,這兩者...
    彥幀閱讀 3,885評論 0 14
  • 1.初識訪問者模式 表示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元...
    王偵閱讀 653評論 0 0

友情鏈接更多精彩內(nèi)容