設計模式(二)——策略模式

一、基本概念

既然你已經接觸到了設計模式,那你大概率你寫過類似這樣的代碼:根據不同的選擇條件(如排序、搜索或路由)執行不同的代碼邏輯。通常的解決方案是使用if-elseswitch語句,但這些條件判斷有一個最大的問題是不夠靈活,難以擴展(也就是違背了開閉原則)。
策略模式是一種行為型設計模式,策略模式提供了一種更優雅的解決方案,你可以定義一系列算法,然后將每個算法封裝成獨立類,使得無需修改核心邏輯就能在不同算法(代碼邏輯)間自由切換。

The algorithm can change without changing the context that uses it.
相比于將所有代碼邏輯硬編碼在一個龐大的類中,更好的方案是編寫不同的策略(算法),然后將它們靈活的插入上下文。

案例類比:去公司的交通方式。
假設你是一只每天可以睡到10點才去上班的哈基米,有以下交通方式可選:
? 共享單車:環保但費力
? 公交:便宜但不夠靈活(可能還要步行一段兒)
? 嘀嘀打車:唯一的缺點就是貴
這些都是交通策略(可以看做一個個獨立的算法)。根據時間、預算或心情,你可以選擇不同策略。決策邏輯不變,只是切換策略而已,這和策略模式在代碼中的使用方式比較相似。

2. 使用案例

2.1 情景引入

擴展剛才的案例,假設你跳槽了,換了一家公司,但你對公司所在位置不熟悉,正在學習軟件開發的你打算開發一個導航應用,支持多種出行方式的路線規劃。

  • 步行路線
  • 自行車路線
  • 公交路線
  • 駕車路線

在v1版本,你只實現了你最常用的公交路線。隨后陸續添加了步行、自行車和駕車等功能。最終你完成了這樣的路線計算方法:

if (mode.equals("bus")) {// 駕車路線代碼邏輯
} else if (mode.equals("walk")) {// 步行路線代碼邏輯
} else if (mode.equals("bike")) {// 自行車路線代碼邏輯
} else { // 其他模式... 
}

隨著路線規劃方式的增加,if-else變得越來越多。如果你打算和朋友協作完成這個項目,你會發現代碼修改不方便,甚至合并時還會產生沖突。

2.2 解決方案——策略模式

2.2.1核心概念
  • 策略接口:聲明算法規約(如execute()方法)。
  • 具體策略:實現策略接口的不同算法。
  • 上下文:持有策略引用并將行為委托給這個引用。
  • 客戶端:選擇使用哪種策略并注入上下文。
2.2.2 Java實現

第一步:定義策略接口

public interface RouteStrategy {String execute();
}

第二步:實現具體策略

// 駕車路線策略
public class DriveStrategy implements RouteStrategy {@Overridepublic String execute() {return "Bike route";}
}// 步行路線策略
public class WalkStrategy implements RouteStrategy {@Overridepublic String execute() {return "Walk route";}
}// 公共交通路線策略
public class MassTransitStrategy implements RouteStrategy {@Overridepublic String execute() {return "MassTransit route";}
}

第三步:上下文類

public class Context {// 注入策略接口(持有引用)private RouteStrategy routeStrategy;public void setRouteStrategy(RouteStrategy routeStrategy) {this.routeStrategy = routeStrategy;}// 行為委托給這個引用public String getRoute() {if (routeStrategy == null) {throw new IllegalStateException("未設置策略!");}return routeStrategy.execute();}
}

第四步:客戶端選擇策略

public class Client {public static void main(String[] args) {Context context = new Context();context.setRouteStrategy(new DriveStrategy());System.out.println("駕車路線: " + context.getRoute());context.setRouteStrategy(new WalkStrategy());System.out.println("步行路線: " + context.getRoute());context.setRouteStrategy(new MassTransitStrategy());System.out.println("公共交通路線: " + context.getRoute());}
}

執行結果
在這里插入圖片描述

3. 策略模式 vs 狀態模式

策略模式(Strategy) 和 狀態模式(State) 看起來很相似:二者都通過委托實現,替換一個實現了相同接口的不同對象。但它們在設計意圖、控制流和動機上存在本質區別。

策略模式狀態模式
設計意圖核心是讓客戶端(外部調用者)選擇具體算法,關注的是可獨立變化的行為。例如上述案例中選擇不同路徑計算邏輯。用于表示一個對象在不同時間點的不同狀態或條件,其狀態轉換由對象自身的內在邏輯決定
控制流客戶端顯式決定使用哪種策略(如通過 setStrategy(…) 動態切換)狀態轉換由上下文對象內部驅動,行為隨狀態自動改變,客戶端通常無需感知具體狀態。
感知與狀態轉換??各策略對象之間??相互獨立??,彼此無感知。例如,快速排序策略無需知道冒泡排序的存在。狀態對象通常??知曉其他狀態??,并能主動觸發轉換。例如,媒體播放器的 PlayingState(播放狀態)可自行切換到 PausedState(暫停狀態)。
使用場景算法可能變化且應由客戶端選擇時對象行為需要根據其生命周期演變時

4. 策略模式適用場景

在以下情況使用策略模式:
? 需要支持多種實現方式(算法)
? 需在運行時切換邏輯
? 希望遵循開閉原則
? 要避免if-else或switch語句膨脹

優缺點分析
優點

? 運行時切換算法
? 符合單一職責原則,代碼更清晰
? 添加新算法不影響核心邏輯
? 便于測試和擴展

缺點
? 需要創建更多類
? 客戶端必須了解策略選擇
? 對簡單任務可能過度設計

5. 總結

策略模式是管理算法變化的優雅方案。通過將行為委托給策略類,避免了if-else語句的混亂。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92536.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92536.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92536.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL基礎知識總結

一、MySQL簡述 數據庫 是一個有組織的集合,用于存儲和管理數據的系統。它是一個軟件系統,被設計用來存儲、檢索和管理數據,并提供數據的快速訪問和處理。數據庫可以被看作是一種特殊的文件系統,但與傳統的文件系統不同的是&#…

數據倉庫命名規范

1. 概述 數據模型是數據管理的分析工具和交流的有力手段;同時,還能夠很好地保證數據的一致性,是實現商務智能(Business Intelligence)的重要基礎。因此建立、管理一個企業級的數據模型,應該遵循標準的命名…

FlinkSQL Joins全解析

1. Lookup Join用途:用于流表與外部維表(靜態或緩慢變化表)的關聯(如 MySQL、HBase 等)。特點:通過 實時查詢外部存儲 獲取維度數據。僅支持 處理時間(Processing Time)語義&#xf…

【FileZilla】基于 FTP 的 Windows 和 Linux 文件傳輸

在嵌入式開發過程中我們經常需要在 Windows 和 Linux 下進行文件傳輸,本文就介紹一種通過 FTP 實現 Windows 和 Linux 文件傳輸的方法。 Windows 為物理主機,Linux 是在 Vmware 虛擬機中安裝運行的 Ubuntu,版本為 18.04。 Ubuntu 安裝 FTP …

【GPT入門】第42課 ollama安裝與運行llama3模型

【GPT入門】第42課 ollama安裝與運行llama3模型1. 安裝ollama2.運行模型3.測試模型3.1 直接在命令行交互3.2 openai接口1. 安裝ollama https://ollama.com/ 選download, 選linux 執行安裝命令: curl -fsSL https://ollama.com/install.sh | sh2.運行模型 啟動服…

Lua語言元表、協同程序

元表元表的定義允許我們改變table的行為。setmetatable(普通表,元表)-- 元表a {"a","b","c"} -- 普通表 b {} --元表c setmetatable(a,b)print("------------------------")f {}print("f:",f)d setmetatabl…

[已解決]VSCode右鍵菜單消失恢復

前言 莫名其妙,好似VSCode自動更新以后,右鍵菜單就失效了,重裝也無果. 手動搞一個吧 保存下面代碼到桌面修復VSCODE右鍵菜單.reg,雙擊運行即可. Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\Directory\Background\shell\VSCode]"使用 VSCode 打開""…

什么是瀏覽器標識?

瀏覽器標識 層面一:網絡層指紋 (HTTP/TLS) 這是最基礎的指紋,即使不用瀏覽器,只用Go的 net/http 發請求也會留下。HTTP Headers (請求頭): User-Agent: 最著名的標識,聲明自己是什么瀏覽器。很容易偽造,但也很容易被識…

五十八、【Linux系統nginx服務】nginx代理服務器、nginx優化

Nginx代理技術全景圖 #mermaid-svg-0dRktnHYPXypO9xB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0dRktnHYPXypO9xB .error-icon{fill:#552222;}#mermaid-svg-0dRktnHYPXypO9xB .error-text{fill:#552222;stroke…

[0CTF 2016]piapiapia

usernamepassword回顯推斷admin123Invalid user name or passwordadmin123Invalid user name or passwordadmin123Invalid user name or passworda123Invalid user name說明username是adminadmin1Invalid password這很奇怪了admin0200?admin11Invalid user name or …

人工智能系列(7)人工神經網絡中的無監督學習

一. 無監督學習簡介神經網絡的一個關鍵屬性是能夠從環境中學習,并在不斷學習的過程中持續改善性能。在無監督學習(又稱自組織學習,self-organized learning)中,網絡無需外部教師提供目標輸出,而是通過對輸入…

250810-OpenWebUI集成Dify應用

A. 最終效果 B. 環境配置 配置并啟動Open-WebUI 隨后瀏覽器訪問:http://localhost:8080 pip install open-webui open-webui serve配置并啟動Pipelines Pipelines默認占用80端口相比于Docker的啟動方式,可以在相同的命令行中,查看pipelines …

day22|學習前端ts語言

抽象類,繼承。不能創造實例class類:屬性聲明,構造器,方法,實例繼承super()override重寫父類繼承的方法聲明提升(hoisting)同一個js作用域內部,編譯階段把函數…

【網絡安全】CTF——[網鼎杯2018]Unfinish-SQL注入-二次注入

目錄 一、前言 二、環境 三、復現 3.1尋找注入點 3.2嘗試盲注 3.3正則限制 3.4腳本注入獲取flag 四、總結 一、前言 前兩天復現了一道CTF題目[網鼎杯 2018]Comment,今天繼續來學習一下SQL二次注入。 二、環境 BUUCTF在線評測 三、…

【langchain】如何給langchain提issue和提pull request?

什么是issue? 可以這么理解,bug是issue的子集。issue可以包含bug\feature\sercurity and others. https://github.com/langchain-ai/langchain/issues/32484 什么是pull request? 其實我真不是很理解,但不妨我來提pr https://github.com/langchain-ai/…

MySQL的存儲引擎:

目錄 InooDB引擎: MyISAM引擎: InooDB引擎與MyISAM存儲引擎的區別: Archive引擎: Blackhole引擎: CSV引擎: Memory引擎: Federated引擎: Merge引擎: NDB引擎&a…

Mock與Stub

一、核心概念與差異對比特性MockStub核心目的驗證對象間的交互行為提供預定義的固定響應驗證重點方法調用次數、參數、順序不關注調用過程,只關注結果行為模擬可編程的智能模擬靜態的簡單響應適用場景驗證協作關系隔離依賴、提供固定數據復雜性較高(需要…

香港服務器容器網絡插件的多節點通信性能基準測試

香港服務器容器網絡插件的多節點通信性能基準測試在云計算和容器化技術快速發展的今天,香港服務器因其優越的地理位置和網絡環境,成為眾多企業部署容器服務的首選。本文將深入探討香港服務器環境下容器網絡插件的多節點通信性能,通過詳實的基…

Vue3 學習教程,從入門到精通,Vue 3 全局 API 語法知識點及案例詳解(32)

Vue 3 全局 API 語法知識點及案例詳解 Vue 3 提供了豐富的全局 API,用于創建應用實例、注冊全局組件、指令、插件等。以下將詳細介紹 Vue 3 的主要全局 API,并結合詳細的案例代碼進行說明。每個案例代碼都包含中文注釋,幫助初學者更好地理解…

UE5多人MOBA+GAS 41、制作一個飛彈,添加準心索敵

文章目錄添加新角色(不寫了)創建一個發射技能創建一個飛彈類添加擊中特效添加準星UI獲取瞄準目標添加新角色(不寫了) 將原本的機器人藍圖改為BP_PlayerCharacter,以此創建子藍圖 創建動畫藍圖模板(具體就…