1. 程式人生 > 其它 >設計模式(二十三)訪問者模式

設計模式(二十三)訪問者模式

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、應用場景:

  1. 物件結構中物件對應的類很少改變,但經常需要在此物件結構上定義新的操作;
  2. 需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而需要避免讓這些操作"汙染"這些物件的類,也不希望在增加新操作時修改這些類。
如本文有侵權行為,請及時與本人聯絡,多多包涵! 小生初出茅廬,多多指教!

本文來自部落格園,作者:it-小林,轉載請註明原文連結:https://www.cnblogs.com/linruitao/p/15067890.html