【設計模式】之策略模式

来源:https://www.cnblogs.com/YWT-Real/archive/2022/09/23/16720704.html
-Advertisement-
Play Games

場景引入 假如你在A城市,要去B城市旅游,交通方式有以下幾種選擇: 駕車 火車 飛機 不難寫出這樣的代碼: void transport(string method) { if (method == "drive") { // 處理駕車相關業務邏輯 } else if (method == "tra ...


場景引入

假如你在A城市,要去B城市旅游,交通方式有以下幾種選擇:

  1. 駕車
  2. 火車
  3. 飛機

不難寫出這樣的代碼:

void transport(string method)
{
    if (method == "drive")
    {
        // 處理駕車相關業務邏輯
    }
    else if (method == "train")
    {
        // 處理乘坐火車相關業務邏輯
    }
    else
    {
        // 處理乘坐飛機相關業務邏輯
    }
}

想一想,有什麼問題?

屏幕前的你應該已經想到了,如果增加一種交通方式的話,是不是得增加if-else分支?這樣就需要大量的修改,不符合開閉原則。

那怎麼樣能做到在不對源代碼直接修改的前提下增加交通方式呢?答案是:把不同交通方式的業務邏輯抽離出來單獨做成介面。

首先我們要定義一個基類Transportation,作為這幾個交通方式的父類。這個Transportation有個純虛函數run,從Transportation派生出DriveTrainPlane等子類(叫做策略類),重寫run函數。這時的類體系如下:

這樣將來如果需要擴展的話,只需要在從Transportation類派生出新的子類了。

代碼如下:

class Transportation
{
public:
    virtual void run() = 0;
}

class Drive : public Transportation
{
public:
    void run() override
    {
        // 處理駕車相關業務邏輯
    }
}

class Train : public Transportation
{
public:
    void run() override
    {
        // 處理乘坐火車相關業務邏輯
    }
}

class Plane : public Transportation
{
public:
    void run() override
    {
        // 處理乘坐飛機相關業務邏輯
    }
?

此時多態就體現出來了,使用不同的類,調用run函數,就會做出不同的行為。

那怎麼樣來使用這些策略類呢?我們再新增一個類Context,可以根據傳入的參數做相應的處理:

class Context
{
    Transportation &strategy;
public:
    explicit Context(Transportation &strategy) : strategy(strategy) { }

    void run()
    {
        strategy.run();
    }
}

定義

策略模式(Strategy Pattern):一個類的行為或其演算法可以在運行時更改的設計模式。(如例子中不同的交通方式)

主要使用場景

有多種演算法,希望避免因為多個if-else分支而帶來的難以維護和擴展的問題。

組成

抽象策略類:定義了不同策略的介面(如例子中的Transportation

具體策略類:具體實現抽象策略類的介面(如例子中的DriveTrainPlane

環境:根據需要進行決策(如例子中的Context

優缺點

優點

  1. 可維護性、可擴展性高。
  2. 對客戶隱藏了具體的實現細節

缺點

  1. 客戶端必須要知道所有的策略類,並自行選擇要用哪一個策略類。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在最新一屆國際資料庫頂級會議 ACM SIGMOD 2022 上,來自清華大學的李國良和張超兩位老師發表了一篇論文:《HTAP Database: What is New and What is Next》,並做了 《HTAP Database:A Tutorial》 的專項報告。這幾期學術分享會的 ...
  • 使用過Redis事務的應該清楚,Redis事務實現是通過打包多條命令,單獨的隔離操作,事務中的所有命令都會按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。事務中的命令要麼全部被執行,要麼全部都不執行(原子操作)。但其中有命令因業務原因執行失敗並不會阻斷後續命令的執行,且也無... ...
  • ​介紹一下個人開發者賬號: 再說下什麼是免費的蘋果開發者賬號,就是你沒交688年費的就是免費賬號,如果你想變成付費開發者賬號,提交申請付費就行,賬號都是一樣的賬號。 沒有賬號的點擊鏈接申請: 蘋果開發者賬號申請 登錄開發者中心developer.apple.com/account這個界面就是免費開發 ...
  • 1、Date => String 代碼 /** * 函數描述:時間格式化工具 * @param format {String} 格式(y-年,M-月,d-日,H-時[24],h-時[12],m-分,s-秒,S-毫秒(3位數),q-季度,ap,午前am/午後pm) * @returns {String ...
  • ##PUT,DELETE,POST,GET四種基礎方法對應增刪改查 1、GET請求會向資料庫發索取數據的請求,從而來獲取信息,該請求就像資料庫的select操作一樣,只是用來查詢一下數據,不會修改、增加數據,不會影響資源的內容,即該請求不會產生副作用。無論進行多少次操作,結果都是一樣的。 2、與GE ...
  • 公粽號【今天也要寫bug】每日推送,歡迎關註 每日3題 1 以下代碼執行後,控制臺中的輸出內容為? const user = { name: "JM", age: 18, }; const data = JSON.stringify(user, ["age"]); console.log(data) ...
  • *AMD* 規範,全稱 *Asynchronous Module Definition*,非同步模塊定義,模塊之間的依賴可以被非同步載入。 AMD 規範由 Common JS 規範演進而來,前文介紹 Common JS 規範時說過,瀏覽器端無法直接使用 Common JS,需要使用 *browseri... ...
  • ## 輸出語句* 1.window.alert() --寫入警告框* 2.document.write() 寫入HTML輸出* 3.console.log() 寫入瀏覽器控制台* alert("hello world!");//寫入警告框document.write("你好世界~");console ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...