Java設計模式之行為型模式(策略模式)介紹與說明

一、策略模式簡介

策略模式(Strategy Pattern)是一種行為型設計模式,它定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。策略模式讓算法獨立于使用它的客戶而變化,屬于對象行為型模式。其核心思想是將算法的定義與使用分離,通過接口或抽象類來定義算法族,具體算法實現由具體策略類完成,客戶端可以根據需要選擇合適的策略。

二、策略模式的結構

  1. 抽象策略(Strategy)角色:這是一個抽象類或接口,定義了算法的公共接口,聲明了算法的方法,所有具體策略類都需實現該接口或繼承該抽象類。它為上下文角色提供一個統一的算法調用接口。
  2. 具體策略(Concrete Strategy)角色:實現了抽象策略接口或繼承了抽象策略類,包含具體的算法實現。可以有多個具體策略類,每個類實現不同的算法,它們之間可以相互替換。
  3. 環境(Context)角色:持有一個對抽象策略角色的引用,負責與具體策略對象交互,它可以在運行時動態地更換策略對象,從而改變其行為。客戶端通過環境角色來間接調用具體策略的算法方法。

三、策略模式的實現步驟

  1. 定義抽象策略接口或抽象類,聲明算法方法。
  2. 創建具體策略類,實現抽象策略接口或繼承抽象策略類,提供具體的算法實現。
  3. 構建環境類,包含一個抽象策略類型的成員變量,提供設置策略的方法,并通過該成員變量調用策略的算法方法。
  4. 客戶端根據需要創建具體策略對象,并將其設置到環境對象中,然后調用環境對象的方法來執行相應的算法。

四、策略模式的優缺點

優點:
  1. 算法的可擴展性強:可以方便地增加新的策略,符合開閉原則。新的策略只需實現抽象策略接口或繼承抽象策略類,無需修改現有代碼。
  2. 避免使用多重條件判斷:將算法封裝在獨立的策略類中,客戶端通過選擇不同的策略來執行不同的算法,避免了在代碼中使用大量的條件判斷語句,使代碼更加簡潔、清晰。
  3. 提高代碼的可維護性:每個策略類都專注于實現一種算法,職責單一,易于理解和維護。當算法需要修改或優化時,只需修改相應的策略類,不會影響其他代碼。
缺點:
  1. 增加了類的數量:每增加一個策略就需要增加一個具體策略類,當策略較多時,會導致系統中類的數量增加,增加系統的復雜性。
  2. 客戶端需要了解所有策略:客戶端需要知道所有的策略類,以便根據需要選擇合適的策略。這增加了客戶端的負擔,同時也可能暴露策略的實現細節。
  3. 策略類之間可能相互依賴:在某些情況下,不同的策略之間可能存在依賴關系,這會增加系統的復雜性,并且可能導致策略之間的耦合度過高。

五、策略模式的應用場景

  1. 當存在多個相關的算法或行為,并且希望在運行時動態地選擇其中的一個時。例如,一個電商系統中,根據不同的促銷活動,可能有多種計算商品價格的策略,如滿減、折扣、贈品等,可以使用策略模式來封裝這些計算價格的算法,在結算時根據當前的促銷活動選擇相應的策略。
  2. 當算法需要頻繁變化或需要被客戶端動態切換時。比如,一個圖像處理軟件中,有多種圖像濾鏡算法,用戶可以根據自己的需求選擇不同的濾鏡效果,這時可以使用策略模式來實現濾鏡算法的切換。
  3. 當不希望條件判斷語句過多,希望通過將算法封裝在獨立的類中來實現算法的靈活切換時。在一些業務邏輯復雜的場景中,可能存在大量的條件判斷來選擇不同的算法或行為,使用策略模式可以將這些條件判斷分散到各個策略類中,使代碼更加簡潔和易于維護。

六、策略模式的示例代碼

以下是一個簡單的Java示例,演示了策略模式的應用。假設有一個鴨子類,鴨子可以有不同的飛行行為,如正常飛行、不會飛行等,使用策略模式來實現鴨子的飛行行為。

// 抽象策略接口
interface FlyBehavior {void fly();
}// 具體策略類:正常飛行
class FlyWithWings implements FlyBehavior {@Overridepublic void fly() {System.out.println("使用翅膀飛行");}
}// 具體策略類:不會飛行
class FlyNoWay implements FlyBehavior {@Overridepublic void fly() {System.out.println("不會飛行");}
}// 環境類:鴨子
class Duck {private FlyBehavior flyBehavior;public void setFlyBehavior(FlyBehavior flyBehavior) {this.flyBehavior = flyBehavior;}public void performFly() {if (flyBehavior!= null) {flyBehavior.fly();} else {System.out.println("沒有設置飛行行為");}}
}// 客戶端代碼
public class StrategyPatternExample {public static void main(String[] args) {Duck duck = new Duck();// 設置鴨子為正常飛行行為duck.setFlyBehavior(new FlyWithWings());duck.performFly();// 切換鴨子為不會飛行行為duck.setFlyBehavior(new FlyNoWay());duck.performFly();}
}

在上述示例中,FlyBehavior是抽象策略接口,FlyWithWingsFlyNoWay是具體策略類,實現了不同的飛行行為。Duck是環境類,持有一個FlyBehavior類型的成員變量,通過setFlyBehavior方法可以動態地設置鴨子的飛行行為,然后調用performFly方法來執行飛行行為。客戶端可以根據需要創建不同的具體策略對象,并將其設置到鴨子對象中,從而實現鴨子飛行行為的動態切換。


總之,策略模式是一種非常實用的行為型設計模式,它可以使算法的定義與使用分離,提高代碼的靈活性、可擴展性和可維護性。在實際開發中,當遇到需要動態選擇算法或行為的場景時,可以考慮使用策略模式來解決問題。

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

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

相關文章

【BIOS+MBR 微內核手寫實現】

本文基于BIOS+MBR的架構,從四部分講解微內核是如何實現的: 1)搭建微內核編譯調試環境 2)梳理微內核的代碼結構:偽指令講解 3)手寫實現微內核框架,輸出簡單的字符串 4)講解微內核啟動階段的具體運行過程 先完成內核工程創建,如下圖 我們這里使用nasm風格的匯編編寫,…

從C/C++遷移到Go:內存管理思維轉變

一、引言 在當今高速發展的軟件開發世界中,語言遷移已成為技術進化的常態。作為一名曾經的C/C開發者,我經歷了向Go語言轉變的全過程,其中最大的認知挑戰來自內存管理模式的根本性差異。 我記得第一次接觸Go項目時的困惑:沒有析構函…

正確設置 FreeRTOS 與 STM32 的中斷優先級

在裸機開發(非 RTOS)時,大多數 STM32 外設的中斷優先級通常不需要手動配置,原因如下: ? 裸機開發中默認中斷優先級行為 特點說明默認中斷優先級為 0如果你不設置,STM32 HAL 默認設置所有外設中斷為 0&…

EasyExcel之SheetWriteHandler:解鎖Excel寫入的高階玩法

引言在 EasyExcel 強大的功能體系中,SheetWriteHandler 接口是一個關鍵的組成部分。它允許開發者在寫入 Excel 的 Sheet 時進行自定義處理,為實現各種復雜的業務需求提供了強大的支持。通過深入了解和運用 SheetWriteHandler 接口,我們能夠更…

Python單例模式魔法方法or屬性

1.單例模式概念定義:單例模式(Singleton Pattern)是一種創建型設計模式,它確保一個類只能有一個實例,并提供一個全局訪問點來獲取該實例。這種模式在需要控制資源訪問、配置管理或協調系統操作時特別有用。核心特點:私有構造函數:防止外部通過…

【Kubernetes系列】Kubernetes 資源請求(Requests)

博客目錄 引言一、資源請求的基本概念1.1 什么是資源請求1.2 請求與限制的區別 二、CPU 請求的深入解析2.1 CPU 請求的單位與含義2.2 CPU 請求的調度影響2.3 CPU 請求與限制的關系 三、內存請求的深入解析3.1 內存請求的單位與含義3.2 內存請求的調度影響3.3 內存請求的特殊性 …

大型語言模型中的自動化思維鏈提示

摘要 大型語言模型(LLMs)能夠通過生成中間推理步驟來執行復雜的推理任務。為提示演示提供這些步驟的過程被稱為思維鏈(CoT)提示。CoT提示有兩種主要范式。一種使用簡單的提示語,如“讓我們一步一步思考”,…

Private Set Generation with Discriminative Information(2211.04446v1)

1. 遇到什么問題,解決了什么遇到的問題現有差分隱私生成模型受限于高維數據分布建模的復雜性,合成樣本實用性不足。深度生成模型訓練依賴大量數據,加入隱私約束后更難優化,且不保證下游任務(如分類)的最優解…

C++編程語言入門指南

一、C語言概述 C是由丹麥計算機科學家Bjarne Stroustrup于1979年在貝爾實驗室開發的一種靜態類型、編譯式、通用型編程語言。最初被稱為"C with Classes"(帶類的C),1983年更名為C。它既具有高級語言的抽象特性,又保留了底層硬件操作能力&…

ZED相機與Foxglove集成:加速機器人視覺調試效率的實用方案

隨著機器人技術的發展,實時視覺數據流的高效傳輸和可視化成為提升系統性能的重要因素。通過ZED相機(包括ZED 2i和ZED X)與Foxglove Studio平臺的結合,開發者能夠輕松訪問高質量的2D圖像、深度圖和點云數據,從而顯著提高…

目標檢測新紀元:DETR到Mamba實戰解析

🚀【實戰分享】目標檢測的“后 DE?”時代:DETR/DINO/RT-DETR及新型骨干網絡探索(含示例代碼) 目標檢測從 YOLO、Faster R-CNN 到 Transformer 結構的 DETR,再到 DINO、RT-DETR,近兩年出現了許多新趨勢&am…

【IOS】XCode創建firstapp并運行(成為IOS開發者)

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 這篇文章主要介紹XCode創建firstapp并運行 學其所用,用其所學。——梁啟超 歡迎來到我的博客,一起學習,共同進步。 喜歡的朋友可以關注一下,下次更新不迷路…

class類和style內聯樣式的綁定 + 事件處理 + uniapp創建自定義頁面模板

目錄 一.class類的綁定 1.靜態編寫 2.動態編寫 二.style內聯樣式的綁定 三.事件處理 1.案例1 2.案例2 四.uniapp創建自定義頁面模板 1.為什么要這么做? 2.步驟 ①打開新建頁面的界面 ②在彈出的目錄下,新建模板文件 ③用HBuilderX打開該模板…

android 卡頓和丟幀區別

Android 卡頓(Jank)與丟幀(Frame Drop)的核心區別在于問題本質與用戶感知,以下是分層解析: ? 一、本質差異 維度卡頓(Jank)丟幀(Frame Drop)定義用戶可感知…

【python實用小腳本-125】基于 Python 的 Gmail 郵件發送工具:實現高效郵件自動化

引言 在現代辦公和開發環境中,郵件通信是一種重要的溝通方式。自動化發送郵件可以大大提高工作效率,例如發送通知、報告或文件。本文將介紹一個基于 Python 的 Gmail 郵件發送工具,它能夠通過 Gmail 的 SMTP 服務器發送郵件,并支持…

gateway斷言配置詳解

一、Predicate - 斷? 1、簡單用法 spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After2017-01-20T17:42:47.789-07:00[America/Denver] 2、自定義斷言 新建類VipRoutePredicateFactory,注意VipRoutePredicateFactory名字…

基于大模型的尿毒癥全流程預測與診療方案研究報告

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與方法 1.3 國內外研究現狀 二、尿毒癥相關理論基礎 2.1 尿毒癥的定義、病因與發病機制 2.2 尿毒癥的癥狀與診斷標準 2.3 尿毒癥的治療方法概述 三、大模型技術原理與應用 3.1 大模型的基本概念與發展歷程 3.2 大模型…

裸金屬服務器租用平臺-青蛙云

企業對服務器性能與靈活性的要求與日俱增。青蛙云M-啟強裸金屬服務器租用平臺應運而生,為企業提供了一種兼具物理機性能和云計算彈性的解決方案。裸金屬服務器租用平臺的優勢?(一)高配性能,無虛擬化開銷?裸金屬服務器直接運行在物理硬件之上&#xff0…

[Terence Tao訪談] AlphaProof系統 | AI嗅覺 | 研究生學習 | 龐加萊猜想(高維) | 復雜問題簡單化

玩這些有趣的東西。通常情況下什么也得不到,你必須學會說:“好吧,再試一次,什么都沒發生,我會繼續前進。” DeepMind的AlphaProof系統 Q:DeepMind的AlphaProof系統是通過強化學習訓練的,使用的…

Aseprite工具入門教程4之動畫導入Unity

1、時間軸功能 (1)眼睛圖標 顯示/隱藏圖層圖層隱藏時無法繪制 (2)鎖定圖標 鎖定后無法移動或編輯圖層防止意外在錯誤圖層上繪制 (3)單元格圖標 兩個點代表幀分開,一個橢圓代表幀統一。分開就…