訪問者模式是一種將演算法與對象結構分離的軟體設計模式。它可以讓你在不修改對象結構的情況下,對對象結構中的元素進行不同的操作。訪問者模式的優點是符合單一職責原則,優秀的擴展性和靈活性。缺點是具體元素對訪問者公佈細節,違反了迪米特原則,而且如果元素類經常變化,會導致訪問者類需要頻繁修改。 訪問者模式適合在 ...
訪問者模式是一種將演算法與對象結構分離的軟體設計模式。它可以讓你在不修改對象結構的情況下,對對象結構中的元素進行不同的操作。訪問者模式的優點是符合單一職責原則,優秀的擴展性和靈活性。缺點是具體元素對訪問者公佈細節,違反了迪米特原則,而且如果元素類經常變化,會導致訪問者類需要頻繁修改。
訪問者模式適合在以下場景下使用:
- 對象結構比較穩定,但經常需要在此對象結構上定義新的操作。
- 需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而需要避免讓這些操作“污染”這些對象的類,也不希望在增加新操作時修改這些類。
- 對象結構中的元素類型很少變化,但每個元素都有很多種變化的可能性,並且每一種變化都影響到元素的行為。
一個訪問者模式的例子。
這個例子中,有一個電腦組件的介面(ComputerPart),它有一個accept方法用來接受訪問者對象(ComputerPartVisitor)。
然後有三個實現了這個介面的類:鍵盤(Keyboard),滑鼠(Mouse)和顯示器(Monitor)。
每個類都實現了accept方法,調用訪問者對象的visit方法,並傳遞自身作為參數。
訪問者對象是一個介面,它有三個visit方法,分別對應三種不同的電腦組件。然後有兩個實現了這個介面的類:電腦顯示訪問者(ComputerDisplayVisitor)和電腦修理訪問者(ComputerRepairVisitor)。
每個類都實現了三個visit方法,分別對不同的電腦組件執行不同的操作。
最後,有一個電腦類(Computer),它包含了三種電腦組件,並且也實現了accept方法,調用每個組件的accept方法,並傳遞自身作為參數。下麵是部分代碼:
// 電腦組件介面 public interface ComputerPart { public void accept(ComputerPartVisitor computerPartVisitor); } // 鍵盤類 public class Keyboard 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 Monitor implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } } // 訪問者介面 public interface ComputerPartVisitor { public void visit(Keyboard keyboard); public void visit(Mouse mouse); public void visit(Monitor monitor); } // 電腦顯示訪問者類 public class ComputerDisplayVisitor implements ComputerPartVisitor { @Override public void visit(Keyboard keyboard) { System.out.println("Displaying Keyboard."); } @Override public void visit(Mouse mouse) { System.out.println("Displaying Mouse."); } @Override public void visit(Monitor monitor) { System.out.println("Displaying Monitor."); } } // 電腦修理訪問者類 public class ComputerRepairVisitor implements ComputerPartVisitor { @Override public void visit(Keyboard keyboard) { System.out.println("Repairing Keyboard."); } @Override public void visit(Mouse mouse) { System.out.println("Repairing Mouse."); } @Override public void visit(Monitor monitor) { System.out.println("Repairing Monitor."); } } // 電腦類 public class Computer implements ComputerPart { private final List<ComputerComponent> components; // 構造函數初始化鍵盤、滑鼠和顯示器 // 實現accept方法 // 調用每個組件的accept方法,並傳遞自身作為參數 }
這段代碼的目的是演示訪問者模式的用法,它定義了一個電腦組件的介面,和三個實現了這個介面的類,分別代表鍵盤、滑鼠和顯示器。這些類都有一個accept方法,用來接受一個訪問者對象,並調用它的visit方法。訪問者對象是一個介面,它有三個visit方法,分別對應三種不同的電腦組件。這個介面有兩個實現類,分別是電腦顯示訪問者和電腦修理訪問者。這兩個類都實現了三個visit方法,分別對不同的電腦組件執行不同的操作。例如,電腦顯示訪問者會列印出每個組件的名稱,而電腦修理訪問者會列印出每個組件正在被修理。最後,有一個電腦類,它包含了三種電腦組件,並且也實現了accept方法。當調用這個方法時,它會遍歷所有的組件,並調用它們的accept方法,並傳遞自身作為參數。這樣就可以根據不同的訪問者對象,在不修改原有類結構和行為的情況下,對每個組件執行不同的操作。
假設我們創建了一個電腦對象,然後分別用電腦顯示訪問者和電腦修理訪問者來訪問它,那麼運行結果可能是這樣的:
// 創建一個電腦對象 Computer computer = new Computer(); // 創建一個電腦顯示訪問者對象 ComputerDisplayVisitor displayVisitor = new ComputerDisplayVisitor(); // 調用電腦的accept方法,並傳遞顯示訪問者對象 computer.accept(displayVisitor); // 輸出結果: Displaying Keyboard. Displaying Mouse. Displaying Monitor. // 創建一個電腦修理訪問者對象 ComputerRepairVisitor repairVisitor = new ComputerRepairVisitor(); // 調用電腦的accept方法,並傳遞修理訪問者對象 computer.accept(repairVisitor); // 輸出結果: Repairing Keyboard. Repairing Mouse. Repairing Monitor.