1、什么是策略模式

在做同一件事时,根据条件的不一样,我们会使用不同的机制或者方法去处理。

举个生活中的例子,我们在饭店吃完饭付钱的时候,扫的那种聚合支付,比如收钱吧。他们就可以说是使用了策略模式。用户无论用支付宝,微信还是云闪付等等,都能直接扫码付款。我们不需要知道它里面的细节,只要知道扫这个码就可以了。

如果不使用策略模式,就是if else。只不过在代码中,如果if else过多,会导致代码维护困难,职责不单一等问题。

2、代码实现

我们来看看代码实现。

下面我们将用代码来实现一个人使用不同的交通工具前往目的地。

不使用策略模式

public class Test {
    
    public static void main(String[] args) {

        // 剩余油量
        Integer innage = 10;

        // 剩余金额
        Integer money = 10;

        // 交通工具
        String vehicle = "bicycle";
        if ("bicycle".equals(vehicle)){
            System.out.println("骑自行车前往目的地");
        } else if ("bus".equals(vehicle)){
            if (money >= 20){
                System.out.println("乘坐公共汽车前往目的地");
            } else{
                System.err.println("余额不足,无法前往");
            }
        } else if("car".equals(vehicle)){
            if (innage >= 5){
                System.out.println("油量充足,开车前往目的地");
            } else{
                System.err.println("油量不足,无法前往");
            }
        }
        
    }
    
}

使用策略模式

交通工具接口类

public interface Vehicle {

    Boolean run(Integer num);

}

自行车实现类,实现了交通工具接口

public class Bicycle implements Vehicle{
    @Override
    public Boolean run(Integer num) {
        System.out.println("骑自行车前往目的地");
        return true;
    }
}

公共汽车实现类,实现了交通工具接口

public class Bus implements Vehicle{

    @Override
    public Boolean run(Integer money) {
        if (money >= 20){
            System.out.println("乘坐公共汽车前往目的地");
            return true;
        } else {
            System.err.println("余额不足,无法前往");
            return false;
        }

    }
}

小汽车实现类,实现了交通工具接口

public class Car implements Vehicle{

    // 剩余油量
    private Integer innage;

    public Integer getInnage() {
        return innage;
    }

    public void setInnage(Integer innage) {
        this.innage = innage;
    }

    public Car(Integer innage) {
        this.innage = innage;
    }

    public Car() {
    }

    @Override
    public Boolean run(Integer num) {
        if (innage > 5){
            System.out.println("油量充足,开车前往目的地");
            return true;
        } else {
            System.err.println("油量不足,无法前往");
            return false;
        }

    }
}

工具类,用于调配具体的策略

public class Tool {

    private Vehicle vehicle;

    public void setVehicle(Vehicle vehicle){
        this.vehicle = vehicle;
    }

    public Boolean got(Integer num){
        if (vehicle == null){
            System.err.println("请选择你的交通工具");
            return false;
        } else {
            return vehicle.run(num);
        }
    }

}

使用交通工具前往目的地

public class People {

    public static void main(String[] args) {
        // 自行车
        Tool tool = new Tool();
        tool.setVehicle(new Bicycle());
        tool.got(10);

        // 公共汽车
        tool.setVehicle(new Bus());
        tool.got(10);

        // 小汽车
        tool.setVehicle(new Car(10));
        tool.got(10);

    }

}

对比分析

代码组织

  • if-else:所有逻辑集中在一个方法中,代码臃肿

  • 策略模式:每个算法独立封装,结构清晰

扩展性

  • if-else:添加交通方式需要修改原有代码

  • 策略模式:只需添加新的策略类,无需修改现有代码

维护性

  • if-else:逻辑耦合,修改一个分支可能影响其他分支

  • 策略模式:各个策略相互独立,易于维护

测试性

  • if-else:需要测试所有分支的组合

  • 策略模式:可以独立测试每个策略

优缺点分析

优点

  • 每个策略独立封装,易于维护和扩展

  • 避免复杂的if-else结构

  • 添加新策略无需修改现有代码

缺点

  • 每个策略都需要一个类,可能会导致类数量过多

  • 客户端需要知道所有的策略,以便选择合适的策略类

  • 每个策略都是对象,会更占内存

3、总结

策略模式带来最大的好处就是,易于维护和扩展。

如果你的业务是固定的,每个条件的业务处理并不复杂,建议不使用策略模式。

如果你的业务是可能会增加条件的,或者说每个条件的业务比较复杂,建议使用策略模式。