設計模式(二十三)訪問者模式
阿新 • • 發佈:2021-10-15
1、定義
封裝某些作用於某種資料結構中各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新操作。
2、型別:行為類模式
3、類圖
主要角色:
抽象訪問者:抽象類或者介面,宣告訪問者可以訪問哪些元素,具體到程式中就是visit方法中的引數定義哪些物件是可以被訪問的;
訪問者:實現抽象訪問者所宣告的方法,它影響到訪問者訪問到一個類後該幹什麼,要做什麼事情;
抽象元素類:抽象類或者介面,宣告接受哪一類訪問者訪問,程式上是通過accept方法中的引數來定義的,抽象類一般有兩類方法,一部分是本身的業務邏輯,另外就是允許接收哪類訪問者 來訪問;
元素類:實現抽象元素類所宣告的accept方法,通常都是visitor.visit(this),基本上已經形成一種定式了;
結構物件:一個元素的容器,一般包含一個容納多個不同類、不同介面的容器,如List、Set、Map等,在專案中一般很少抽象出這個角色。
4、程式碼例項
1 /** 2 * @author it-小林 3 * @desc 元素介面 4 * @date 2021年10月14日 19:38 5 */ 6 public interface ComputerPart { 7 8 public void accept(ComputerPartVisitor computerPartVisitor);9 }
1 /** 2 * @author it-小林 3 * @desc 訪問者介面 4 * @date 2021年10月14日 19:39 5 */ 6 public interface ComputerPartVisitor { 7 public void visit(Computer computer); 8 public void visit(Mouse mouse); 9 public void visit(Keyboard keyboard); 10 public void visit(Monitor monitor); 11}
1 /** 2 * @author it-小林 3 * @desc 滑鼠 4 * @date 2021年10月14日 19:44 5 */ 6 public class Mouse implements ComputerPart{ 7 8 @Override 9 public void accept(ComputerPartVisitor computerPartVisitor) { 10 computerPartVisitor.visit(this); 11 } 12 }
1 /** 2 * @author it-小林 3 * @desc 鍵盤 4 * @date 2021年10月14日 19:40 5 */ 6 public class Keyboard implements ComputerPart{ 7 @Override 8 public void accept(ComputerPartVisitor computerPartVisitor) { 9 computerPartVisitor.visit(this); 10 } 11 }
1 /** 2 * @author it-小林 3 * @desc 顯示器 4 * @date 2021年10月14日 19:42 5 */ 6 public class Monitor implements ComputerPart{ 7 @Override 8 public void accept(ComputerPartVisitor computerPartVisitor) { 9 computerPartVisitor.visit(this); 10 } 11 }
1 /** 2 * @author it-小林 3 * @desc 電腦 4 * @date 2021年10月14日 19:45 5 */ 6 public class Computer implements ComputerPart{ 7 ComputerPart[] parts; 8 9 public Computer() { 10 parts = new ComputerPart[]{new Mouse(), new Keyboard(), new Monitor()}; 11 } 12 13 @Override 14 public void accept(ComputerPartVisitor computerPartVisitor) { 15 for (ComputerPart computerPart: parts) { 16 computerPart.accept(computerPartVisitor); 17 } 18 computerPartVisitor.visit(this); 19 } 20 }
1 /** 2 * @author it-小林 3 * @desc 具體訪問者 4 * @date 2021年10月14日 19:51 5 */ 6 public class ComputerPartDisplayVisitor implements ComputerPartVisitor{ 7 8 @Override 9 public void visit(Computer computer) { 10 System.out.println("Displaying Computer."); 11 } 12 13 @Override 14 public void visit(Mouse mouse) { 15 System.out.println("Displaying Mouse."); 16 } 17 18 @Override 19 public void visit(Keyboard keyboard) { 20 System.out.println("Displaying Keyboard."); 21 } 22 23 @Override 24 public void visit(Monitor monitor) { 25 System.out.println("Displaying Monitor."); 26 } 27 }
1 /** 2 * @author it-小林 3 * @desc 客戶端 4 * @date 2021年10月14日 19:54 5 */ 6 public class Client { 7 public static void main(String[] args) { 8 ComputerPart computer = new Computer(); 9 computer.accept(new ComputerPartDisplayVisitor()); 10 } 11 }
5、優點
- 符合單一職責原則;
- 優秀的擴充套件性;
- 靈活性。
6、缺點
- 具體元素對訪問者公佈細節,違反了迪米特原則;
- 具體元素變更比較困難;
- 違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
7、應用場景:
- 物件結構中物件對應的類很少改變,但經常需要在此物件結構上定義新的操作;
- 需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而需要避免讓這些操作"汙染"這些物件的類,也不希望在增加新操作時修改這些類。
本文來自部落格園,作者:it-小林,轉載請註明原文連結:https://www.cnblogs.com/linruitao/p/15067890.html