【设计模式】访问者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
文章目錄
- 一、訪問者模式簡介
- 二、訪問者模式 適用場景
- 三、訪問者模式 優缺點
- 四、訪問者模式 與 迭代器模式
- 五、代碼示例
- 1、Game 父類 ( 被訪問者 )
- 2、VipGame 收費游戲 ( 被訪問者 )
- 3、FreeGame 免費游戲 ( 被訪問者 )
- 4、IVisitor 訪問者接口
- 5、VipVisitor 付費玩家
- 6、測試類
一、訪問者模式簡介
訪問者模式 : 封裝 作用于 某種 數據結構 的 各元素 操作 , 數據結構指的是 List , Set , Map 等 ;
在 不改變 元素類 的前提下 , 定義 作用于 元素 的操作 ;
訪問者模式類型 : 行為型 ;
二、訪問者模式 適用場景
訪問者模式 適用場景 :
-
List , Set , Map 等 數據結構 中 , 包含 很多類型的對象 ;
-
數據結構 與 數據操作 分離 ;
三、訪問者模式 優缺點
訪問者模式 優點 : 訪問者模式 增加新的操作 很容易 , 只需要增加一個新的 訪問者 即可 ; 將相關的行為 , 封裝到一個 訪問者 中 ;
訪問者模式 缺點 :
- 增加 新 數據結構 比較困難 ;
- 元素變更 比較困難 ; 如 為 被訪問 的對象 增加 / 減少 一些屬性 , 相應的 訪問者 也需要進行修改 ;
四、訪問者模式 與 迭代器模式
訪問者模式 與 迭代器模式 都是在 某種 數據結構 ( List / Set / Map ) 上進行處理 ;
訪問者模式 主要用于 對 保存在 數據結構 中元素 , 進行某種特定處理 , 重點是 處理 ;
迭代器模式 主要作用就是 遍歷 數據結構 中的元素 , 重點是 遍歷 ;
五、代碼示例
游戲 分為 免費游戲 和 收費游戲 , 玩家 分為 免費玩家 和 付費玩家 ;
不同的玩家 , 訪問不同的游戲 , 各自有不同的效果 ;
被訪問者 , 都繼承自同一個父類 , 可以放在一個集合中 ;
訪問者 , 都實現同一個接口 , 針對每個類型的被訪問者 , 都有一個對應的重載方法 ;
如 : 玩家訪問者 , 對免費游戲有一個方法 , 對收費游戲也有一個方法 ;
該設計模式不常用 , 如果遇到 數據加載 與 數據操作 分離的情況 , 可以考慮使用 訪問者模式 ;
大部分情況下 , 用不到 , 但是一旦需要用到的時候 , 訪問者模式是唯一的解決方案 ;
1、Game 父類 ( 被訪問者 )
package visitor;/*** 游戲父類 , 所有的游戲都要繼承該類* VipGame 和 FreeGame 都繼承 Game , 這兩個都是 Game**/ public abstract class Game {/*** 游戲名稱*/private String mGameName;public String getGameName() {return mGameName;}public void setGameName(String gameName) {this.mGameName = gameName;}/*** 當有訪問者要訪問游戲時 , 將訪問者傳入該方法* 用于判定訪問者是否有權限訪問游戲* @param visitor*/public abstract void accept(IVisitor visitor); }
2、VipGame 收費游戲 ( 被訪問者 )
package visitor;public class VipVisitor implements IVisitor {/*** 訪問免費游戲 , 打印游戲名稱* @param freeGame*/@Overridepublic void visit(FreeGame freeGame) {System.out.println("我是 VIP , 可以訪問免費游戲 : " + freeGame.getGameName());}/*** 訪問收費游戲 , 打印游戲名稱和價格* @param vipGame*/@Overridepublic void visit(VipGame vipGame) {System.out.println("我是 VIP , 可以訪問收費游戲 : " + vipGame.getGameName() + " , 價格 : " + vipGame.getmVipPrice());} }
3、FreeGame 免費游戲 ( 被訪問者 )
package visitor;/*** 免費游戲*/ public class FreeGame extends Game {@Overridepublic void accept(IVisitor visitor) {visitor.visit(this);} }
4、IVisitor 訪問者接口
package visitor;/*** 該接口中聲明了兩個重載方法* 訪問 FreeGame 的 visit 方法* 訪問 VipGame 的 visit 方法** 在 Game 中調用 visit 方法 , 將自身傳遞到 visit 方法作為參數* 分別調用不同的重載方法** 訪問者可以擴展很多了 , 可以定義若干實現了 IVisitor 接口的訪問者* 每個 Visistor 訪問者 , 訪問不同的游戲 , 有不同的表現 , 如 :* 白嫖訪問者 , 不花錢 , 只能玩免費游戲 , 不能玩收費游戲* 付費訪問者 , 購買 VIP , 可以同時玩免費和收費游戲** 對于免費游戲來說 , 傳入任何訪問者都可以訪問 ;* 對于收費游戲來說 , 傳入付費訪問者, 才可以訪問 ;** 相同的 Visitor 對不同的數據產生不同的行為* 不同的 Visitor 對相同的數據產生不同的行為*/ public interface IVisitor {/*** 訪問免費游戲* @param freeGame*/void visit(FreeGame freeGame);/*** 訪問收費游戲* @param vipGame*/void visit(VipGame vipGame); }
5、VipVisitor 付費玩家
package visitor;public class VipVisitor implements IVisitor {/*** 訪問免費游戲 , 打印游戲名稱* @param freeGame*/@Overridepublic void visit(FreeGame freeGame) {System.out.println("我是 VIP , 可以訪問免費游戲 : " + freeGame.getGameName());}/*** 訪問收費游戲 , 打印游戲名稱和價格* @param vipGame*/@Overridepublic void visit(VipGame vipGame) {System.out.println("我是 VIP , 可以訪問收費游戲 : " + vipGame.getGameName() + " , 價格 : " + vipGame.getmVipPrice());} }
6、測試類
package visitor;import java.util.ArrayList;public class Main {public static void main(String[] args) {// 創建存放 Game 的集合ArrayList<Game> games = new ArrayList<>();// 創建免費游戲FreeGame freeGame = new FreeGame();freeGame.setGameName("超級馬里奧");games.add(freeGame);// 創建收費游戲VipGame vipGame = new VipGame();vipGame.setGameName("絕地求生");vipGame.setmVipPrice(88);games.add(vipGame);// Vip 訪問者訪問免費和收費游戲for (Game game : games) {game.accept(new VipVisitor());}} }
運行結果 :
總結
以上是生活随笔為你收集整理的【设计模式】访问者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】Android Studio
- 下一篇: 【设计模式】状态模式 ( 简介 | 适用