设计模式篇——策略模式

本文介绍了策略模式在解决多算法选择问题时的应用,通过一个旅游选择交通工具的例子,展示了如何用策略模式替代传统的if...else语句,使得代码更加清晰、可扩展。在改造后的代码中,定义了策略接口和具体策略类,实现了根据不同交通工具选择的动态切换,降低了耦合度。同时,文章还探讨了策略模式的优缺点以及在实际应用中的场景,如Spring框架中的Resource接口和DispatcherServlet。
摘要由CSDN通过智能技术生成

设计模式篇——策略模式

一、应用场景

1.1 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

1.2 一个系统需要动态地在几种算法中选择一种。

1.3 如果一个对象有很多的行为,如果不用恰当的设计模式,这些行为就只好使用多重的if条件选择语句来实现。

二、介绍

定义:

定义了算法族,分别封装起来,让他们之间可以互相替换,此模式的变化独立于算法的使用者

主要解决:

在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

策略模式涉及到三个角色:

  • Strategy:策略接口或者策略抽象类,用来约束一系列的策略算法(Context 使用这个接口来调用具体的策略实现算法)
  • ConcreateStrategy:具体的策略类(实现策略接口或继承抽象策略类)
  • Context:上下文类,持有具体策略类的实例,并负责调用相关的算法

三、实现

假设我们目前有这样一个场景:我们要出门旅游,此时需要选择交通工具

传统写法:

/**
 * @author jiangfeilong
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("准备旅游,开始选择交通工具。。。");
        int i = new Scanner(System.in).nextInt();
        if (i == 1) {
            System.out.println("选择了私家车");
        } else if (i == 2) {
            System.out.println("选择了火车");
        } else if (i == 3) {
            System.out.println("选择了飞机");
        }
    }
}

策略模式改造后:

/**
 * @author jiangfeilong
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("准备旅游,开始选择交通工具。。。");
        //这里就把三种交通工具直接封装好,供调用者直接选择,避免了多重if...else
        SelectVehicleContext car = new CarVehicleContext();
        SelectVehicleContext train = new TrainVehicleContext();
        SelectVehicleContext airplane = new AirplaneVehicleContext();
        //选择私家车
        car.select();
    }
}

/**
 * 交通工具抽象
 */
interface VehicleStrategy {
    /**
     * 选择的实际交通工具
     */
    void vehicle();
}

/**
 * 选择交通工具
 */
abstract class SelectVehicleContext {

    public SelectVehicleContext(VehicleStrategy vehicleStrategy) {
        this.vehicleStrategy = vehicleStrategy;
    }

    protected VehicleStrategy vehicleStrategy;

    abstract void select();
}

/**
 * 私家车
 */
class CarVehicleContext extends SelectVehicleContext {
    /**
     * 这里提供一个默认的解决方案
     */
    public CarVehicleContext() {
        super(() -> System.out.println("选择私家车出行"));
    }

    public CarVehicleContext(VehicleStrategy vehicleStrategy) {
        super(vehicleStrategy);
    }

    @Override
    void select() {
        //这里具体选择的交通工具就看用户传递什么交通工具
        //这里也可以根据不同的实现类需求,写不同业务逻辑
        vehicleStrategy.vehicle();
    }
}

/**
 * 火车
 */
class TrainVehicleContext extends SelectVehicleContext {
    public TrainVehicleContext() {
        super(() -> System.out.println("选择火车出行"));
    }

    public TrainVehicleContext(VehicleStrategy vehicleStrategy) {
        super(vehicleStrategy);
    }

    @Override
    void select() {
        vehicleStrategy.vehicle();
    }
}

/**
 * 飞机
 */
class AirplaneVehicleContext extends SelectVehicleContext {
    public AirplaneVehicleContext() {
        super(() -> System.out.println("选择飞机出行"));
    }

    public AirplaneVehicleContext(VehicleStrategy vehicleStrategy) {
        super(vehicleStrategy);
    }

    @Override
    void select() {
        vehicleStrategy.vehicle();
    }
}

四、总结

看完这个示例是不是感觉非常简单,其实在实际应用过程中,ConcreateStrategy策略类的具体实现过程会根据应用场景的不同而复杂程度也不同,比如一些复杂的应用场景一个支付接口需要提供多种支付渠道,下面将放上几个框架中已经使用到策略模式的应用场景:
Spring中Resource接口

SpringMVC中DispatcherServlet

优点:

结构清晰明了、使用简单直观

耦合度相对而言较低,扩展方便

操作封装也更为彻底,数据更为安全

缺点:

策略类数量会增多,每个策略都是一个类,复用的可能性很小

所有的策略类都需要对外暴露

代码复杂性增高

总而言之任何东西都是有利有弊,希望小伙伴们可以在适合的时机用上它

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

指陆为码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值