策略模式(Strategy Pattern)
定義
定義一系列演算法類,將每一個演算法封裝起來,並讓它們可以相互替換,策略模式讓演算法獨立於使用它的客戶而變化,也稱為政策模式(Policy)。
設計的原則和思想
- 解耦策略的定義、建立和使用這三部分。
- 不變部分是演算法本身,變化的部分是演算法的呼叫。
- 核心思想是動態確定演算法(變化)。
一句話概括設計模式
相同的介面,相同的方法,不同的策略。
結構中包含的角色
- Strategy(抽象策略類)
- ConcreteStrategy(具體策略類)
- Context(環境類)
最小可表達程式碼
abstract class AbstractStrategy
{
public abstract function algorithm();
}
class ConcreteStrategy extends AbstractStrategy
{
public function algorithm()
{
echo "具體演算法";
}
}
class Context
{
private $strategy;
public function __construct(AbstractStrategy $strategy)
{
$this->strategy = $strategy;
}
public function algorithm()
{
$this->strategy->algorithm();
}
}
$context = new Context(new ConcreteStrategy());
$context->algorithm();
優點
- 可以自由切換演算法。
- 避免了多重條件判斷。
- 演算法單獨提取到策略類中,提供了一種演算法的複用機制。
缺點
- 因為需要選擇合適的策略,客戶端需要知道所有的策略演算法。
- 任何的變化都將導致系統要增加一個新的具體策略類。
- 客戶端每次只能使用一個策略類。
何時使用
- 需要動態地切換不同演算法。
- 一個物件有很多的行為,將這些行為轉移到相應的具體策略類可以避免維護多重條件語句。
實際應用場景
- 出行是騎腳踏車, 坐汽車還是走路。
- 一條魚可以清蒸、紅燒、炭烤等。
- 處理訂單是同步還是非同步。
- 日誌記錄到資料庫,檔案還是快取。
注意
- 演算法很少發生改變就沒有必要使用這個模式了,使用會讓程式更復雜。
- 如果策略多餘4個,那麼需要使用多個設計模式混合了來解決策略類膨脹的問題了。
策略的定義、建立和使用
策略的定義
一個策略介面和一組實現這個介面的策略類。
策略的建立
為了封裝建立邏輯,可以把根據 type 建立策略的邏輯抽離出來,放到工廠類中。
策略的使用
執行時動態確定使用哪種策略,這也是策略模式最典型的應用場景。
本作品採用《CC 協議》,轉載必須註明作者和本文連結