满纸荒唐言,一把心酸泪,都云作者痴,谁解其中味。 技术博客 心情随笔 登录
策略模式
2025/11/20 15

导航

1前言

2从一个简单的例子开始

3策略模式的实现

4策略模式的总结

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

<全文完>

赞同 0
反对 0
登录注册会员 后发表评论。
评论列表