1. 程式人生 > >設計模式(二十二)—— 策略模式

設計模式(二十二)—— 策略模式

條件 封裝 兩種 模式 類圖 contex tex 圖片 系列

模式簡介


定義一系列的算法,把它們一個個封裝起來,並且使它們可互相替換。本模式使得算法可獨立於使用它的客戶而變化。

策略模式也被稱為政策模式,它是一種行為型模式。為了完成某一項任務,往往可以有很多種不同的方式,例如商場促銷,有不同的促銷手段,比如提價50滿100減20、原價兩倍打八折等等,這每一種方式我們稱之為策略。為了避免將策略硬編碼在程序當中,可以使用策略模式,在系統運行過程中根據具體的環境或者條件執行不同的策略。

結構分析


UML類圖

技術分享圖片

角色說明

  • Context

上下文類。包含一個對Strategy對象的引用,提供一個方法配置ConcreteStrategy對象,實現算法的動態替換。

  • Strategy

策略接口。定義算法的公共接口,Context類通過這個接口調用具體策略的算法。

  • ConcreteStrategy

具體策略。實現策略接口,定義具體算法。

工作原理

Context類提供一個方法(SetStrategy)設置具體算法,並將該對象的引用保存到私有變量_strategy中。Context將客戶端請求轉發給_strategy對象,完成策略調用。

結構代碼

//策略接口
interface IStrategy
{
    void AlgorithmInterface();
}

//上下文類
class Context
{
    private IStrategy _strategy;
    public void SetStrategy(IStrategy strategy)
    {
        _strategy = strategy;
    }
    public void ContextInterface()
    {
        _strategy.AlgorithmInterface();
    }
}

//具體策略A
class ConcreteStrategyA : IStrategy
{
    public void AlgorithmInterface()
    {
        Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
    }
}

//具體策略B
class ConcreteStrategyB : IStrategy
{
    public void AlgorithmInterface()
    {
        Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
    }
}

//客戶端調用
class Program
{
    static void Main(string[] args)
    {
        Context context = new Context();
        context.SetStrategy(new ConcreteStrategyA());
        context.ContextInterface();
        context.SetStrategy(new ConcreteStrategyB());
        context.ContextInterface();
        Console.ReadLine();
    }
}

程序輸出:

技術分享圖片

示例分析


本節我們依然實現文章開頭中的示例,首先聲明ISalesPromotion接口。

public interface ISalesPromotion
{
    void Calculate(int orgPrice);
}

分別實現提價50滿100減20以及原價兩倍打八折兩種銷售策略。

public class Reduction : ISalesPromotion
{
    public void Calculate(int orgPrice)
    {
        var price = orgPrice + 50 - 20;
        Console.WriteLine($"Original Price : [{orgPrice}] , Price : [{price}]");
    }
}

public class Discount : ISalesPromotion
{
    public void Calculate(int orgPrice)
    {
        var price = orgPrice * 2 * 0.8;
        Console.WriteLine($"Original Price : [{orgPrice}] , Price : [{price}]");
    }
}

創建產品類

public class Product
{
    private ISalesPromotion _promotion;
    public void SetPromotion(ISalesPromotion promotion)
    {
        _promotion = promotion;
    }
    public void PrintPrice(int price)
    {
        _promotion.Calculate(price);
    }
}

客戶端調用

class Program
{
    static void Main(string[] args)
    {
        int price1 = 120;
        Product p1 = new Product();
        //設置促銷策略為滿減
        p1.SetPromotion(new Reduction());
        p1.PrintPrice(price1);

        int price2 = 500;
        Product p2 = new Product();
        //設置促銷策略為打折
        p2.SetPromotion(new Discount());
        p2.PrintPrice(price2);

        Console.ReadLine();
    }
}

程序輸出

技術分享圖片

使用場景


  • 許多相關的類僅僅時行為上有差異。策略模式可以動態地讓一個對象在眾多行為中選擇一種行為。

  • 一個系統需要動態地在幾種算法中選擇一種。
  • 一個對象有很多行為,並且這些行為在這個類的操作中以多個條件語句的形式出現。
  • 不希望客戶知道復雜的、與算法相關的數據結構,在具體策略類中封裝算法和相關的數據結構,提高算法的保密性及安全性。

設計模式(二十二)—— 策略模式