策略模式(Strategy Pattern)——算法的封裝與切換

說明:設計模式系列文章是讀劉偉所著《設計模式的藝術之道(軟件開發人員內功修煉之道)》一書的閱讀筆記。個人感覺這本書講的不錯,有興趣推薦讀一讀。詳細內容也可以看看此書作者的博客https://blog.csdn.net/LoveLion/article/details/17517213

模式概述

俗話說:條條大路通羅馬。在很多情況下,實現某個目標的途徑不止一條,例如我們在外出旅遊時可以選擇多種不同的出行方式,如騎自行車、坐汽車、坐火車或者坐飛機。

這就是變化的地方,可根據實際情況(距離、預算、時間、舒適度等)來選擇一種出行方式。

在軟件開發中,也常會遇到類似的情況,實現某一個功能有多種算法,此時就可以使用一種設計模式來實現靈活地選擇解決途徑,也能夠方便地增加新的解決途徑。

下面介紹一種爲了適應算法靈活性而產生的設計模式——策略模式。

模式定義

策略模式的主要目的是將算法的定義與使用分開,也就是將算法的行爲和環境分開。

將算法的定義放在專門的策略類中,每一個策略類封裝了一種實現算法,使用算法的環境類針對抽象策略類進行編程,符合依賴倒轉原則。在出現新的算法時,只需要增加一個新的實現了抽象策略類的具體策略類即可。

策略模式定義如下:

策略模式(Strategy Pattern):定義一系列算法類,將每一個算法封裝起來,並讓它們可以相互替換,策略模式讓算法獨立於使用它的客戶而變化,也稱爲政策模式(Policy)。策略模式是一種對象行爲型模式。

模式結構圖

策略模式結構並不複雜,但我們需要理解其中環境類Context的作用,其結構如下圖所示:

在策略模式結構圖中包含如下幾個角色:

  • Context(環境類):環境類是使用算法的角色,它在解決某個問題(即實現某個方法)時可以採用多種策略。在環境類中維持一個對抽象策略類的引用實例,用於定義所採用的策略。
  • Strategy(抽象策略類):它爲所支持的算法聲明瞭抽象方法,是所有策略類的父類,它可以是抽象類或具體類,也可以是接口。環境類通過抽象策略類中聲明的方法在運行時調用具體策略類中實現的算法。
  • ConcreteStrategy(具體策略類):它實現了在抽象策略類中聲明的算法,在運行時,具體策略類將覆蓋在環境類中定義的抽象策略類對象,使用一種具體的算法實現某個業務處理。

模式僞代碼

抽象策略類(Strategy)典型代碼如下:

/**
 * 定義抽象算法
 */
public interface Strategy {
    
    void algorithm();
}

具體策略類(ConcreteStrategy)封裝每一種具體的算法,典型代碼如下:

/**
 * 一種具體的算法
 */
public class ConcreteStrategy implements Strategy {

    @Override
    public void algorithm() {
        // 具體的算法實現
    }
}

Context引用抽象策略,典型代碼如下:

public class Context {

    // 抽象策略
    private Strategy strategy;

    /**
     * 業務邏輯
     */
    public void service() {

        // ...

        // 調用具體的算法實現
        strategy.algorithm();

        // ...
    }
}

這樣就將算法的定義和使用分離開來,可獨立擴展新的算法。

模式應用

待完善。

模式總結

策略模式提供了一種可插拔式(Pluggable)算法的實現方案。

策略模式實用性強、擴展性好,在軟件開發中得以廣泛使用,是使用頻率較高的設計模式之一。

主要優點

  • 符合開閉原則,可以在不修改原有系統的基礎上選擇算法或行爲,也可以靈活地增加新的算法或行爲
  • 將算法的定義和使用分離開來,符合單一職責原則,可最大程度地複用算法

主要缺點

系統可能會產生很多具體策略類。

適用場景

策略模式用於算法的自由切換和擴展。

策略模式對應於解決某一問題的一個算法族,允許用戶從該算法族中任選一個算法來解決某一問題,同時可以方便地更換算法或者增加新的算法。

只要涉及到算法的封裝、複用和切換都可以考慮使用策略模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章