java 中的訪客模式示例
Visitor
模式允許你向一組類新增新操作或方法,而無需修改這些類的結構。
當你想要在物件上集中特定操作而不擴充套件物件或不修改物件時,此模式特別有用。
來自維基百科的 UML 圖:
程式碼段:
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);
}
}
}
說明:
Visitable
(Element
)是一個介面,這個介面方法必須新增到一組類中。Visitor
是一個介面,它包含對Visitable
元素執行操作的方法。GameVisitor
是一個類,它實現了Visitor
介面(ConcreteVisitor
)。- 每個
Visitable
元素接受Visitor
並呼叫Visitor
介面的相關方法。 - 你可以將
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
用例/適用性:
- 必須對分組在結構中的不同型別的物件執行類似的操作
- 你需要執行許多不同且不相關的操作。它將操作與物件結構分開
- 必須新增新操作而不改變物件結構
- *將相關操作收集到單個類中,*而不是強制你更改或派生類
- 將函式新增到你沒有源或無法更改源的類庫 **
其他參考: