导航
1前言
1 前言
策略模式是使用广泛且非常重要的一种设计模式,从编码的角度,它能够优雅的解决if...else if...多层叠加的问题。从软件架构设计的角度,它更浓缩为大名鼎鼎的面向接口编程(或称之为面向抽象编程)。GoF提出的23种设计模式中,面向接口贯穿于其中的20种,其重要性可见一斑。对于软件开发人员,掌握策略模式及其核心的面向抽象编程理念,是从业余爱好到专职码农进化过程中必不可少的一个环节。来源:https://www.wubayue.com
2 从一个简单的例子开始
我们每天上班通勤,可以选择不同的交通工具,如果用最简单的代码实现,会像下面这样:
// 通勤方式
public enum TransportationMode
{
// 公交
Bus,
// 地铁
Metro
}
// 通勤小助手
public class TransportationAssistant
{
public void GoToWork(TransportationMode mode)
{
if (mode == TransportationMode.Bus)
{
// 公交出行
}
else if (mode == TransportationMode.Metro)
{
// 地铁出行
}
// 通勤方式增加时,需要扩展else,不符合开闭原则
}
}
// 客户端
public class Client
{
public static void main()
{
TransportationAssistant assistant = new TransportationAssistant();
assistant.GoToWork(TransportationMode.Metro);
}
}
代码非常简单,在GoToWork()中根据不同的通勤方式参数,安排对应的通勤出行逻辑。来源:https://www.wubayue.com
3 策略模式的实现
上一章节中的代码,如果需要扩展通勤方式,就需要对GoToWork()方法进行修改,这并不符合“开闭原则”,虽然看似将每种通勤方式都封装在一个else if代码块中并不影响其它逻辑,但在实际项目中,情况要复杂的多,因为修改通勤A导致通勤B出现BUG的情况司空见惯,而看似教条的“开闭原则”实则是建立在无数代码血泪教训之上,它从架构设计层面规避了因为修改不相关代码而引入BUG的风险。
章节2中的实现,在小型项目简单场景中完全没有问题并且是推荐的,比如个人的上班通勤,就三五种方式,使用if...else if简单明了,无需过度设计。而一个企业级的出差通勤系统,或是软件架构层面的规划,则需要考虑“开闭原则”和引入策略模式。
// 抽象的通勤策略
public interface ITransportation
{
void GoToWork();
}
// 公交通勤策略
public class TransportationBus : ITransportation
{
public void GoToWork()
{ }
}
// 地铁通勤策略
public class TransportationMetro : ITransportation
{
public void GoToWork()
{ }
}
// 通勤小助手
public class TransportationAssistant
{
public TransportationAssistant(ITransportation transportation)
{
Transportation = transportation;
}
public ITransportation Transportation { get; set; }
public void GoToWork()
{
// 不论扩展出多少种通勤方式,它们之间均不会相互影响,符合开闭原则
this.Transportation.GoToWork();
}
}
// 客户端
public class Client
{
public static void main()
{
ITransportation transportation = new TransportationMetro();
TransportationAssistant assistant = new TransportationAssistant(transportation);
assistant.GoToWork();
}
}
策略模式引入了一个抽象通勤策略(接口),然后将不同的通勤方式封装在不同的具体策略中,对于调用者而言,只需关注抽象无需了解具体实现细节,同时可以灵活的切换不同的策略。来源:https://www.wubayue.com
4 策略模式的总结
从示例中的前后代码对比,策略模式看似只将if...else if代码块中的逻辑迁移至单独的类中,有些同学会觉得不过如此,使不使用策略模式好像影响不大。其实策略模式的深层思想是面向抽象编程,它鼓励我们找到软件中可能变化的部分,通过“抽象-多种实现”的方式进行封装,从而提供符合“开闭原则”可灵活切换的基础范式。
优点
1、符合开闭原则
2、策略可复用
3、单元测试友好
缺点
1、客户端需要了解所有策略,知道有哪些策略可用来源:https://www.wubayue.com
<全文完>