【Design Pattern】Strategy 策略模式

將行為封裝成一個個可互換的策略,並通過選擇來執行策略。

以下就以減重為例說明策略模式。

首先,將要執行的行為定義為一個介面

public interface IWeightLossStrategy
{
    void Execute(Person person);
}

接著實作減重策略,我們的策略有節食、運動…等等

public class DietStrategy : IWeightLossStrategy
{
    public void Execute(Person person)
    {
        Console.WriteLine($"{person.Name} go on a diet.");
    }
}

public class ExerciseStrategy : IWeightLossStrategy
{
    public void Execute(Person person)
    {
        Console.WriteLine($"{person.Name} do exercise.");
    }
}

最後定義一個類(Context)來使用以上定義的策略

public class Person
{
    public string Name { get; set; }
    private IWeightLossStrategy? _strategy;

    public Person(string name)
    {
        Name = name;
    }

    public void SetStrategy(IWeightLossStrategy? strategy)
    {
        _strategy = strategy;
    }

    public void LoseWeight()
    {
        _strategy?.Execute(this);
    }
}

使用方式如下

static void Main(string[] args)
{
    Person person = new Person("Ama");
    person.SetStrategy(new DietStrategy());
    person.LoseWeight();//Ama go on a diet.

    person.SetStrategy(new ExerciseStrategy());
    person.LoseWeight();//Ama do exercise.
}

套用策略模式雖然可以帶來靈活性跟可擴展性,但也或多或少的增加程式的複雜度,因此,判斷一個情境是否適合使用策略模式,並確保使用之後能帶來實質的效益,是我們需要重點學習的部分。


除了每個策略新增一個類別以外,也可以用委派的方式達到一樣的效果

public delegate void WeightLossStrategy(Person person);
public class Person
{
    public string Name { get; set; }
    private WeightLossStrategy? _strategy;

    public Person(string name)
    {
        Name = name;
    }

    public void SetStrategy(WeightLossStrategy? strategy)
    {
        _strategy = strategy;
    }

    public void LoseWeight()
    {
        _strategy?.Invoke(this);
    }
}
static void Main(string[] args)
{
    Person person = new Person("Ama");
    person.SetStrategy(p => Console.WriteLine($"{p.Name} go on a diet."));
    person.LoseWeight();//Ama go on a diet.

    person.SetStrategy(p => Console.WriteLine($"{p.Name} do exercise."));
    person.LoseWeight();//Ama do exercise.
}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *