设计模式学习之策略模式

本文介绍了策略模式在行为设计模式中的应用,它能将具体的算法实现从业务处理中分离,形成可互换的算法类。通过一个简单的计算器示例,展示了使用if-else和策略模式的对比。在策略模式中,算法实现被封装到独立的策略类,由上下文类负责调用,使得代码更加灵活,易于维护和扩展。文章还提供了策略模式的UML类图,并强调了正确使用策略模式的关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言 策略模式是行为设计模式的一种,也是替代⼤量 ifelse 的利器。
在这里插入图片描述

1 策略模式的功能

策略模式的功能是把具体的算法实现,从具体的业务处理里面独立出来,实现成为单独的算法类(封装算法),从而形成一系列的算法,并让这些算法可以相互替换。策略模式的重心不是如何实现算法,而是如何组织和调用这些算法,从而让程序的结构更灵活,具有更好的维护性和扩展性。

1.1 实现一个计算器

以菜鸟教程中的计算器示例代码为例,使用if-else实现和策略模式两种实现方式进行对比。本文的代码均使用Java语言编写。

1.1.1 使用if-else实现

package dp.strategy.example4;

public class Calculator {
    /**
     * 根据输入的参数和运算符做加减乘除运算,最简单的计算器不考虑异常情况
     * @param num1 输入运算数值1
     * @param num2 输入运算数值2
     * @param operation 预算符
     * @return 返回结果
     */
    public double doOperation(int num1, int num2, String operation) {
        if ("+".equals(operation)) {
            System.out.println(num1 + "+" + num2 + "=" + (num1 + num2));
            return num1 + num2;
        } else if ("-".equals(operation)) {
            System.out.println(num1 + "-" + num2 + "=" + (num1 - num2));
            return num1 - num2;
        } else if ("*".equals(operation)) {
            System.out.println(num1 + "*" + num2 + "=" + (num1 * num2));
            return num1 * num2;
        } else if ("/".equals(operation)) {
            System.out.println(num1 + "/" + num2 + "=" + (num1 / num2));
            return num1 / num2;
        }

        return 0;
    }
}

1.1.2 使用策略模式实现

使用策略模式实现的代码会稍微复杂一些,将计算逻辑和调用计算的代码解耦了,其类图为:
在这里插入图片描述
源代码:

package dp.strategy.example5;

// 创建接口
public interface CalculatorStrategy {
    public double doOperation(int num1, int num2);
}

// 创建实现接口的实现类,这里实现了加减乘三种运算
public class OperationAdd implements CalculatorStrategy{

    @Override
    public double doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

public class OperationMultiply implements CalculatorStrategy{
    @Override
    public double doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

public class OperationSubtract implements CalculatorStrategy{
    @Override
    public double doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

// 创建上下文类用于调用具体的实现策略类
public class Context {
    private CalculatorStrategy calculatorStrategy;

    public Context(CalculatorStrategy strategy) {
        this.calculatorStrategy = strategy;
    }

    public double executeStrategy(int num1, int num2) {
        return calculatorStrategy.doOperation(num1, num2);
    }
}

// 创建一个用户(调用方)类,调用不同的实现策略类
public class CalculatorClient {
    public static void main(String[] args) {
        Context context = new Context(new OperationAdd());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

        context = new Context(new OperationSubtract());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

        context = new Context(new OperationMultiply());
        System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
    }
}

2 策略模式和if-else写法的对比

如果在Client中直接使用if-else,或者将具体的实例化判断逻辑放在简单工厂方法中,都不是策略模式。一定要切记策略模式是一种行为型设计模式,其特点是:**通过抽象出策略接口,将具体的策略实现细节下放到了实现类当中,通过传参的形式将具体的策略传给Context,并将策略方法的调用封装在了Context中。**如此一来,便可以在Client(调用方)中根据对应应用场景向Context传入对应的实现类实例即可,基本就不再需要写if-else了。

当然也存在某些业务场景,仍然需要在Client中使用if-else判断生成哪个具体的实现类,在这种场景下我建议直接在Client中引入工厂模式进行重构,基本上能够消灭掉if-else了。

3 UML图

策略模式的类图如下:
在这里插入图片描述
对应plantUML图的代码:

@startuml

skinparam linetype ortho

package "Strategy" <<Frame>> {
  interface Strategy {
    + method()
  }

  class ConcreteStrategyA {
    + method()
  }

  class ConcreteStrategyB {
    + method()
  }

  class ConcreteStrategyC {
    + method()
  }
  
  class ConcreteStrategyD {
    + method()
  }

  class Context {
    - strategy
    + setStrategy(strategy)
    + execute()
  }

  note left of Context
    // 在execute中调用具体策略实现类中的method()
    execute() {
      strategy.method()
    }
    end note

  Strategy <|.. ConcreteStrategyA
  Strategy <|.. ConcreteStrategyB
  Strategy <|.. ConcreteStrategyC
  Strategy <|.. ConcreteStrategyD

  Context o--> Strategy

}
@enduml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值