策略模式(Strategy Pattern)詳解
一、策略模式簡介
策略模式(Strategy Pattern) 是一種 行為型設計模式(對象行為型模式),它定義了一系列算法,并將每一個算法封裝起來,使它們可以互相替換,獨立于使用它們的客戶端。
又稱為政策(Policy)模式。
每一個封裝算法的類稱之為策略(Strategy)類。
策略模式提供了一種可插入式(Pluggable)算法的實現方案。
你可以把它理解為:
“一個工具箱里有多個工具,你可以在不同場景下選擇不同的工具來完成任務。”
在策略模式中,這些“工具”就是各種具體的策略類,而“任務執行者”則是使用這些策略的對象。
(旅游出行方式)
實現某個目標的途徑不止一條,可根據實際情況選擇一條合適的途徑。
軟件開發:
多種算法,例如排序、查找、打折等
使用硬編碼(Hard Coding)實現將導致系統違背開閉原則,擴展性差,且維護困難
可以定義一些獨立的類來封裝不同的算法,每一個類封裝一種具體的算法 —> 策略類
public class Context
{……public void algorithm(String type) {......if(type == "strategyA"){//算法A}else if(type == "strategyB"){//算法B}else if(type == "strategyC"){//算法C}......}……
}
策略模式包含以下3個角色:
Context(環境類)
Strategy(抽象策略類)
ConcreteStrategy(具體策略類)
二、解決的問題類型
策略模式主要用于解決以下問題:
- 同一行為具有多種實現方式:比如支付方式可以是支付寶、微信、銀行卡等。
- 避免大量的 if-else 或 switch-case 判斷邏輯:提高代碼可讀性和擴展性。
- 希望在運行時動態切換算法或行為:比如根據用戶等級選擇不同的折扣策略。
三、使用場景
場景 | 示例 |
---|---|
不同支付方式 | 支付寶、微信、銀聯等 |
折扣計算 | 普通會員、VIP會員、超級會員等不同折扣規則 |
物流配送 | 順豐、京東、德邦等不同物流策略 |
游戲角色技能 | 角色攻擊方式隨武器變化而變化 |
四、核心結構
策略模式通常包含三個部分:
- 策略接口(Strategy):定義所有策略共有的行為。
- 具體策略類(Concrete Strategies):實現接口中的具體行為。
- 上下文類(Context):持有一個策略接口的引用,負責調用策略方法。
五、實際代碼案例(Java)
我們以電商系統中的“支付方式”為例,演示策略模式的使用。
1. 定義策略接口
// 支付策略接口
public interface PaymentStrategy {void pay(int amount);
}
2. 實現具體策略類
// 微信支付策略
public class WeChatPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("WeChat Pay: $" + amount);}
}// 支付寶支付策略
public class AliPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("AliPay: $" + amount);}
}// 銀行卡支付策略
public class BankCardPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Bank Card Pay: $" + amount);}
}
3. 創建上下文類
// 上下文類:支付環境
public class ShoppingCart {private PaymentStrategy paymentStrategy;// 設置策略public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 使用策略進行支付public void checkout(int amount) {if (paymentStrategy == null) {throw new IllegalStateException("Please select a payment strategy.");}paymentStrategy.pay(amount);}
}
4. 客戶端測試類
public class Client {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用微信支付cart.setPaymentStrategy(new WeChatPay());cart.checkout(100);// 切換為支付寶支付cart.setPaymentStrategy(new AliPay());cart.checkout(200);// 切換為銀行卡支付cart.setPaymentStrategy(new BankCardPay());cart.checkout(300);}
}
輸出結果:
WeChat Pay: $100
AliPay: $200
Bank Card Pay: $300
典型代碼(C++)
典型的抽象策略類代碼
abstract class AbstractStrategy
{public abstract void Algorithm(); //聲明抽象算法
}
典型的抽象策略類代碼
class ConcreteStrategyA : AbstractStrategy
{
//算法的具體實現
public override void Algorithm()
{//算法A
}
}
典型的環境類代碼
class Context
{private AbstractStrategy strategy; //維持一個對抽象策略類的引用public void SetStrategy(AbstractStrategy strategy) {this.strategy = strategy;}//調用策略類中的算法public void Algorithm() {strategy.Algorithm();}
}
典型的客戶端代碼片段
……
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA(); //可在運行時指定類型,通過配置文件和反射機制實現
context.SetStrategy(strategy);
context.Algorithm();
……
其他案例
- 某軟件公司為某電影院開發了一套影院售票系統,在該系統中需要為不同類型的用戶提供不同的電影票打折方式,具體打折方案如下:
(1) 學生憑學生證可享受票價8折優惠。
(2) 年齡在10周歲及以下的兒童可享受每張票減免10元的優惠(原始票價需大于等于20元)。
(3) 影院VIP用戶除享受票價半價優惠外還可進行積分,積分累計到一定額度可換取電影院贈送的獎品。
該系統在將來可能還要根據需要引入新的打折方式。現使用策略模式設計該影院售票系統的打折方案
- 排序策略
某系統提供了一個用于對數組數據進行操作的類,該類封裝了對數組的常見操作,如查找數組元素、對數組元素進行排序等。現以排序操作為例,使用策略模式設計該數組操作類,使得客戶端可以動態地更換排序算法,可以根據需要選擇冒泡排序或選擇排序或插入排序,也能夠靈活地增加新的排序算法。
- 旅游出行策略
旅游出行方式可以有多種,如可以乘坐飛機旅游,也可以乘火車旅游,如果有興趣自行車游也是一種極具樂趣的出行方式。不同的旅游出行方式有不同的實現過程,客戶根據自己的需要選擇一種合適的旅游方式。在本實例中我們用策略模式來模擬這一過程。
六、優缺點分析
優點 | 描述 |
---|---|
? 解耦 | 將算法和使用它的對象分離,降低耦合度 |
? 易于擴展 | 新增策略只需新增類,符合開閉原則。提供了對開閉原則的完美支持,用戶可以在不修改原有系統的基礎上選擇算法或行為,也可以靈活地增加新的算法或行為 |
? 運行時可切換策略 | 提供更高的靈活性 |
? 減少冗長的條件判斷語句 | 替代 if-else 或 switch-case 結構 |
其他 | 提供了管理相關的算法族的辦法,提供了一種可以替換繼承關系的辦法,提供了一種算法的復用機制,不同的環境類可以方便地復用策略類 |
缺點 | 描述 |
---|---|
? 增加類數量 | 每個策略對應一個類,可能導致類膨脹,將造成系統產生很多具體策略類 |
? 需要對外暴露策略類 | 客戶端需了解所有策略才能選擇使用哪個 |
? 不適合簡單分支邏輯 | 如果策略種類很少,使用策略模式反而增加了復雜度 |
其他 | 無法同時在客戶端使用多個策略類 |
七、與其他模式對比(補充)
模式名稱 | 目標 |
---|---|
模板方法模式 | 在父類定義算法骨架,子類實現具體步驟 |
責任鏈模式 | 請求在鏈上傳遞,每個節點決定是否處理請求 |
策略模式 | 多種算法/行為封裝成策略,運行時可切換 |
八、最終小結
策略模式是一種非常實用的設計模式,適用于那些具有多種實現方式、需要靈活切換的業務邏輯。它通過將行為抽象為接口和實現類,使得程序更加清晰、易維護、易擴展。
在開發電商系統、支付模塊、權限控制、游戲邏輯等項目中,策略模式都能發揮重要作用。
📌 一句話總結:
策略模式就像“萬能遙控器”,可以自由切換不同的功能模塊,讓程序更靈活、更具適應性。
? 推薦使用方式:
- 對于固定的行為,但實現方式多樣的場景優先考慮策略模式;
- 可結合工廠模式統一創建策略實例,提升管理效率;
- 使用 Lambda 表達式簡化簡單策略的實現(如 Java 8+);
部分內容由AI大模型生成,注意識別!