將行為封裝成一個個可互換的策略,並通過選擇來執行策略。
以下就以減重為例說明策略模式。
首先,將要執行的行為定義為一個介面
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.
}