大聪明教你学Java设计模式 | 第十二篇:策略模式

3,097 阅读5分钟

前言

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。

🍊支持作者: 点赞👍、关注💖、留言💌~

大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

策略模式

🍓🍓什么是策略模式🍓🍓

在讲解策略模式之前,我们先来看一下它的定义👇

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在上面的定义中我们可以提取到两个关键词,它们分别是策略和更改。策略指的是可以实现目标的方案集合;更改则代表了在某些特定情况下,策略之间可以相互替换。其实我们可以用一句话来总结策略模式:针对不同的场景,做出不同的处理策略。

策略模式相对来说更容易理解,同时我们生活中也有很多关于策略模式的实例。我们每个人都点过外卖,不同的外卖平台上都有着不同的优惠政策,比如满减、外卖红包等等,其中每一个优惠政策都具体包含了很多个具体的优惠方案。在满减活动中有满20元减5元、满30元减10元等等;外卖红包中则包含了5元红包、10元红包等等。每一个优惠政策下的多个优惠方案都是一个策略。并且这些策略之间是相互排斥、且可以替换的,并且这些策略也是有一定的优先级顺序的。

我们再举个更简单的小例子:四则运算是数学中最基本的运算规则,在四则运算中包含了加、减、乘、除四种不同的运算方式,这四种运算方式就是具体的策略,我们在计算不同的题目时,就需要从这四种运算方式中选出最合适的一种,选择计算方式的过程就是策略之间的替换。

说到这可能就有小伙伴会说了:用策略模式多麻烦呀,我们直接用 if-else 进行判断不行吗?稍安勿躁,接下来我们就通过代码来实现一下策略模式,通过代码我们就能明白为什么不能用 if-else 做判断了☕~

🍓🍓策略模式的实现🍓🍓

我们就用代码简单的实现一下外卖优惠策略的小例子👇

🍎🍎定义一个优惠策略接口🍎🍎

/**
 * 优惠策略
 * @description: Strategy
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:08
 **/
public interface Strategy {

    /**
     * 具体优惠方式接口
     */
    public String discount();
}

🍎🍎实现优惠策略接口🍎🍎

/**
 * 策略实现类-1
 * @description: StrategyImpl1
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:11
 **/
class StrategyImpl1 implements Strategy{

    @Override
    public String discount() {
        return "满20元减5元";
    }
}

/**
 * 策略实现类-2
 * @description: StrategyImpl2
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:11
 **/
class StrategyImpl2 implements Strategy{

    @Override
    public String discount() {
        return "满30元减10元";
    }
}

/**
 * 策略实现类-3
 * @description: StrategyImpl2
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:11
 **/
class StrategyImpl3 implements Strategy{

    @Override
    public String discount() {
        return "5元优惠红包";
    }
}

/**
 * 策略实现类-4
 * @description: StrategyImpl2
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:11
 **/
class StrategyImpl4 implements Strategy{

    @Override
    public String discount() {
        return "10元优惠红包";
    }
}

🍎🍎定义 Context 类(切换策略) 🍎🍎

/**
 * 切换策略
 * @description: Context
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:14
 **/
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy){
        this.strategy = strategy;
    }

    public String executeStrategy(){
        return strategy.discount();
    }
}

🍎🍎使用 Context 来查看当它改变策略 Strategy 时的行为变化🍎🍎

/**
 * @description: Test
 * @author: 庄霸.liziye
 * @create: 2022-04-12 10:20
 **/
public class Test {

    public static void main(String[] args) {
        Context context = new Context(new StrategyImpl1());
        System.out.println("优惠方式1:" + context.executeStrategy());

        context = new Context(new StrategyImpl2());
        System.out.println("优惠方式2:" + context.executeStrategy());

        context = new Context(new StrategyImpl3());
        System.out.println("优惠方式3:" + context.executeStrategy());

        context = new Context(new StrategyImpl4());
        System.out.println("优惠方式4:" + context.executeStrategy());
    }
}

🍎🍎运行结果🍎🍎

在这里插入图片描述

🍋 看到这相信各位小伙伴就明白为什么不能用 if-else 进行切换了,策略模式可以帮助我们砍掉过多的 if-else 或 switch-case 语句,可以让代码的可读性和扩展性得到提高。我们可以想想,如果使用 if-else 或 switch-case 来切换策略的话,一旦此时有大几十个甚至上百个策略需要我们调用,那么我们就需要写几百行 if-else 或 switch-case 来帮我们判断,这个代码就毫无可读性可言了,没准过一阵子开发者自己回头再看代码的时候,自己都得看懵了😵

🍓🍓策略模式的优、缺点🍓🍓

最后我们总结一下策略模式的优点与缺点👇

🍌🍌优点🍌🍌

可以砍掉代码中过多的 if-else 或 switch-case 语句,使代码更加整洁优雅,一定程度上提高了性能;不同的策略之间可以自由的切换,让代码更灵活,扩展性更高。

🍌🍌缺点🍌🍌

如果场景过多,会产成过多的策略类,一定程度上增加了理解成本,同时我们需要将所有策略类都暴露在外面。

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●'◡'●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西