面向对象的设计原则中提到,开闭原则,对扩展开放,对修改关闭,这要求我们在实现需求时,尽可能通过扩展来实现,而不是通过修改现有代码实现,牵一发动全身,谁知道我们的一点点修改会不会导致大厦倾倒呢。
策略模式就是在需要多种策略选择使用的场景下一种设计模式,例如当我们出差时,可以选择大巴,高铁,飞机等,请客户吃饭可以吃川菜,吃粤菜,吃鲁菜等,不同的需求的情况下要求我们选择不同策略。这种情况下,简单通过多重条件语句实现,不仅语句复杂,而且需要修改代码,严重违背了开闭原则,这时候策略模式就登场了,能够很好的解决这个问题。
策略模式的定义:将一系列的策略,抽象成类,并继承同一个接口,实现互换替代,不应现使用策略的用户。该设计模式属于对象行为模式。
优点:
1. 支持开闭原则,可以在不修改原代码的情况下,扩充新算法。
2. 提供行为的不同实现,用户可以根据不同场景选择不同策略。
3. 将行为封装,与用户分离开来,,实现了使用者与行为分离,低耦合的代码实现。
缺点:
1. 将会封装很多策略类,增加了维护的难度。
代码如下:
namespace Designmode.Strategy
{
/// <summary>
/// 统一的行为接口
/// </summary>
public interface IStrategy
{
/// <summary>
/// 策略行为
/// </summary>
void DoSomething();
}
}
using System;
namespace Designmode.Strategy
{
/// <summary>
/// 策略A的实现类
/// </summary>
public class StrategyA : IStrategy
{
public void DoSomething()
{
Console.WriteLine("do strategy A");
}
}
}
using System;
namespace Designmode.Strategy
{
/// <summary>
/// 策略B的实现类
/// </summary>
public class StrategyB : IStrategy
{
public void DoSomething()
{
Console.WriteLine("do strategy B");
}
}
}
using System;
namespace Designmode.Strategy
{
/// <summary>
/// 策略的使用者
/// </summary>
public class User
{
/// <summary>
/// 用户名称
/// </summary>
public string Name { get; set; }
}
}
using Designmode.Strategy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Designmode
{
class Program
{
static void Do(User usr, IStrategy s)
{
//TODO: usr 使用s做某些事情
s?.DoSomething();
Console.WriteLine($"{usr.Name} do something");
}
static void Main(string[] args)
{
#region 策略模式
User usera = new User() {Name ="A" };
User userb = new User() { Name = "b" };
Do(usera, new StrategyA());
Do(userb, new StrategyB());
#endregion
}
}
}