java 中的訪客模式示例

Visitor 模式允許你向一組類新增新操作或方法,而無需修改這些類的結構。

當你想要在物件上集中特定操作而不擴充套件物件或不修改物件時,此模式特別有用。

來自維基百科的 UML 圖:

StackOverflow 文件

程式碼段:

import java.util.HashMap;

interface Visitable{
    void accept(Visitor visitor);
}

interface Visitor{
    void logGameStatistics(Chess chess);
    void logGameStatistics(Checkers checkers);
    void logGameStatistics(Ludo ludo);    
}
class GameVisitor implements Visitor{
    public void logGameStatistics(Chess chess){
        System.out.println("Logging Chess statistics: Game Completion duration, number of moves etc..");    
    }
    public void logGameStatistics(Checkers checkers){
        System.out.println("Logging Checkers statistics: Game Completion duration, remaining coins of loser");    
    }
    public void logGameStatistics(Ludo ludo){
        System.out.println("Logging Ludo statistics: Game Completion duration, remaining coins of loser");    
    }
}

abstract class Game{
    // Add game related attributes and methods here
    public Game(){
    
    }
    public void getNextMove(){};
    public void makeNextMove(){}
    public abstract String getName();
}
class Chess extends Game implements Visitable{
    public String getName(){
        return Chess.class.getName();
    }
    public void accept(Visitor visitor){
        visitor.logGameStatistics(this);
    }
}
class Checkers extends Game implements Visitable{
    public String getName(){
        return Checkers.class.getName();
    }
    public void accept(Visitor visitor){
        visitor.logGameStatistics(this);
    }
}
class Ludo extends Game implements Visitable{
    public String getName(){
        return Ludo.class.getName();
    }
    public void accept(Visitor visitor){
        visitor.logGameStatistics(this);
    }
}

public class VisitorPattern{
    public static void main(String args[]){
        Visitor visitor = new GameVisitor();
        Visitable games[] = { new Chess(),new Checkers(), new Ludo()};
        for (Visitable v : games){
            v.accept(visitor);
        }
    }
}

說明:

  1. VisitableElement)是一個介面,這個介面方法必須新增到一組類中。
  2. Visitor 是一個介面,它包含對 Visitable 元素執行操作的方法。
  3. GameVisitor 是一個類,它實現了 Visitor 介面(ConcreteVisitor)。
  4. 每個 Visitable 元素接受 Visitor 並呼叫 Visitor 介面的相關方法。
  5. 你可以將 Game 視為 Element,將具體遊戲如 Chess,Checkers and Ludo 視為 ConcreteElements

在上面的例子中,Chess, Checkers and Ludo 是三種不同的遊戲(和 Visitable 類)。在一個晴朗的日子裡,我遇到了記錄每個遊戲統計資料的場景。因此,如果不修改單個類來實現統計功能,你可以將該職責集中在 GameVisitor 類中,這樣可以在不修改每個遊戲結構的情況下為你提供幫助。

輸出:

Logging Chess statistics: Game Completion duration, number of moves etc..
Logging Checkers statistics: Game Completion duration, remaining coins of loser
Logging Ludo statistics: Game Completion duration, remaining coins of loser

用例/適用性:

  1. 必須對分組在結構中的不同型別的物件執行類似的操作
  2. 你需要執行許多不同且不相關的操作。它將操作與物件結構分開
  3. 必須新增新操作而不改變物件結構
  4. *將相關操作收集到單個類中,*而不是強制你更改或派生類
  5. 將函式新增到你沒有源或無法更改源的類庫 **

其他參考:

oodesign

sourcemaking