我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java怎么优雅的使用策略模式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java怎么优雅的使用策略模式

本篇内容介绍了“Java怎么优雅的使用策略模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    什么是策略模式

    策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化。

    简单理解就是,针对不同的场景,使用不同的策略进行处理。

    策略模式结构

    Java怎么优雅的使用策略模式

    • Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。

    • Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。

    策略模式适用场景

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

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

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

    • 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。

    生活中比较常见的应用模式有:

    • 电商网站支付方式,一般分为银联、微信、支付宝,可以采用策略模式。

    • 电商网站活动方式,一般分为满减送、限时折扣、包邮活动,拼团等可以采用策略模式。

    简单示例

    场景:最近太热了,想要降降温,有什么办法呢

    首先,定义一个降温策略的接口

    public interface CoolingStrategy {        void handle();}

    定义3种降温策略;实现策略接口

    public class IceCoolingStrategy implements CoolingStrategy {    @Override    public void handle() {        System.out.println("使用冰块降温");    }}
    public class FanCoolingStrategy implements CoolingStrategy {    @Override    public void handle() {        System.out.println("使用风扇降温");    }}
    public class AirConditionerCoolingStrategy implements CoolingStrategy {    @Override    public void handle() {        System.out.println("使用空调降温");    }}

    定义一个降温策略的上下文

    public class CoolingStrategyContext {    private final CoolingStrategy strategy;    public CoolingStrategyContext(CoolingStrategy strategy) {        this.strategy = strategy;    }    public void coolingHandle() {        strategy.handle();    }}

    测试

    public class Main {    public static void main(String[] args) {                CoolingStrategyContext context = new CoolingStrategyContext(new FanCoolingStrategy());        context.coolingHandle();        context = new CoolingStrategyContext(new AirConditionerCoolingStrategy());        context.coolingHandle();        context = new CoolingStrategyContext(new IceCoolingStrategy());        context.coolingHandle();    }}

    运行结果:

    使用风扇降温 
    使用空调降温 
    使用冰块降温 

    以上就是一个策略模式的简单实现

    项目实战

    场景

    模拟在购买商品时候使用的各种类型优惠券(满减、直减、折扣、n元购)

    这个场景几乎也是大家的一个日常购物省钱渠道,购买商品的时候都希望找一些优惠券,让购买的商品更加实惠。而且到了大促的时候就会有更多的优惠券需要计算那些商品一起购买更加优惠!

    用一坨坨代码实现

    public class CouponDiscountService {    public double discountAmount(int type, double typeContent, double skuPrice, double typeExt) {        // 1. 直减券        if (1 == type) {            return skuPrice - typeContent;        }        // 2. 满减券        if (2 == type) {            if (skuPrice < typeExt) return skuPrice;            return skuPrice - typeContent;        }        // 3. 折扣券        if (3 == type) {            return skuPrice * typeContent;        }        // 4. n元购        if (4 == type) {            return typeContent;        }        return 0D;    }}
    • 以上是不同类型的优惠券计算折扣后的实际金额。

    • 入参包括;优惠券类型、优惠券金额、商品金额,因为有些优惠券是满多少减少多少,所以增加了typeExt类型。这也是方法的不好扩展性问题。

    • 最后是整个的方法体中对优惠券抵扣金额的实现,最开始可能是一个最简单的优惠券,后面随着产品功能的增加,不断的扩展if语句。实际的代码可能要比这个多很多

    策略模式重构代码

    Java怎么优雅的使用策略模式

    • 整体的结构模式并不复杂,主要体现的不同类型的优惠券在计算优惠券方式的不同计算策略。

    • 这里包括一个接口类(ICouponDiscount)以及四种优惠券类型的实现方式。

    • 最后提供了策略模式的上下控制类处理,整体的策略服务。

    代码实现

    优惠券接口

    public interface ICouponDiscount<T> {        BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);}
    • 定义了优惠券折扣接口,也增加了泛型用于不同类型的接口可以传递不同的类型参数。

    • 接口中包括商品金额以及出参返回最终折扣后的金额,这里在实际开发中会比现在的接口参数多一些,但核心逻辑是这些。

    优惠券接口实现

    满减

    public class MJCouponDiscount implements ICouponDiscount<Map<String,String>>  {        public BigDecimal discountAmount(Map<String,String> couponInfo, BigDecimal skuPrice) {        String x = couponInfo.get("x");        String o = couponInfo.get("n");        // 小于商品金额条件的,直接返回商品原价        if (skuPrice.compareTo(new BigDecimal(x)) < 0) return skuPrice;        // 减去优惠金额判断        BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(o));        if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;        return discountAmount;    }}

    直减

    public class ZJCouponDiscount implements ICouponDiscount<Double>  {        public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {        BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(couponInfo));        if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;        return discountAmount;    }}

    折扣

    public class ZKCouponDiscount implements ICouponDiscount<Double> {        public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {        BigDecimal discountAmount = skuPrice.multiply(new BigDecimal(couponInfo)).setScale(2, BigDecimal.ROUND_HALF_UP);        if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;        return discountAmount;    }}

    N元购

    public class NYGCouponDiscount implements ICouponDiscount<Double> {        public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {        return new BigDecimal(couponInfo);    }}

    以上是四种不同类型的优惠券计算折扣金额的策略方式,可以从代码中看到每一种优惠方式的优惠金额。

    策略控制类

    public class Context<T> {    private ICouponDiscount<T> couponDiscount;    public Context(ICouponDiscount<T> couponDiscount) {        this.couponDiscount = couponDiscount;    }    public BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice) {        return couponDiscount.discountAmount(couponInfo, skuPrice);    }}
    • 策略模式的控制类主要是外部可以传递不同的策略实现,在通过统一的方法执行优惠策略计算。

    • 另外这里也可以包装成map结构,让外部只需要对应的泛型类型即可使用相应的服务。

    测试类

    public class ApiTest {    private Logger logger = LoggerFactory.getLogger(ApiTest.class);    @Test    public void test_zj() {        // 直减;100-10,商品100元        Context<Double> context = new Context<Double>(new ZJCouponDiscount());        BigDecimal discountAmount = context.discountAmount(10D, new BigDecimal(100));        logger.info("测试结果:直减优惠后金额 {}", discountAmount);    }    @Test    public void test_mj() {        // 满100减10,商品100元        Context<Map<String,String>> context = new Context<Map<String,String>>(new MJCouponDiscount());        Map<String,String> mapReq = new HashMap<String, String>();        mapReq.put("x","100");        mapReq.put("n","10");        BigDecimal discountAmount = context.discountAmount(mapReq, new BigDecimal(100));        logger.info("测试结果:满减优惠后金额 {}", discountAmount);    }    @Test    public void test_zk() {        // 折扣9折,商品100元        Context<Double> context = new Context<Double>(new ZKCouponDiscount());        BigDecimal discountAmount = context.discountAmount(0.9D, new BigDecimal(100));        logger.info("测试结果:折扣9折后金额 {}", discountAmount);    }    @Test    public void test_nyg() {        // n元购;100-10,商品100元        Context<Double> context = new Context<Double>(new NYGCouponDiscount());        BigDecimal discountAmount = context.discountAmount(90D, new BigDecimal(100));        logger.info("测试结果:n元购优惠后金额 {}", discountAmount);    }}
    • 以上四组测试分别验证了不同类型优惠券的优惠策略,测试结果是满足我们的预期。

    • 这里四种优惠券最终都是在原价100元上折扣10元,最终支付90元。

    “Java怎么优雅的使用策略模式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Java怎么优雅的使用策略模式

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Java怎么优雅的使用策略模式

    本篇内容介绍了“Java怎么优雅的使用策略模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是策略模式策略模式是一种行为型模式,它将对象
    2023-07-05

    详解Java如何优雅的使用策略模式

    设计模式是软件设计中常见问题的典型解决方案。它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。今天就拿其中一个问题来分析如何优雅的使用策略模式吧
    2023-02-27

    java策略模式怎么应用

    策略模式是一种行为型设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。这样就可以使算法的变化独立于使用算法的客户。在Java中,策略模式的应用可以通过以下步骤实现:1. 定义一个接口,该接口声明了所有算法的方法。``
    2023-08-31

    Java策略模式怎么实现

    这篇文章主要介绍“Java策略模式怎么实现”,在日常操作中,相信很多人在Java策略模式怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java策略模式怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来
    2023-06-02

    怎么理解Java设计模式的策略模式

    这篇文章主要讲解了“怎么理解Java设计模式的策略模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Java设计模式的策略模式”吧!一、什么是策略模式策略模式定义了一系列算法,并将每
    2023-06-25

    Android设计模式之策略模式怎么使用

    本篇内容主要讲解“Android设计模式之策略模式怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android设计模式之策略模式怎么使用”吧!1、收到需求假设我们需要自定义的 View
    2023-07-05

    Java的策略模式用代码怎么实现

    这篇文章主要介绍“Java的策略模式用代码怎么实现”,在日常操作中,相信很多人在Java的策略模式用代码怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的策略模式用代码怎么实现”的疑惑有所帮助!
    2023-06-29

    java设计模式的策略模式是什么

    这篇文章主要介绍“java设计模式的策略模式是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java设计模式的策略模式是什么”文章能帮助大家解决问题。策略模式亦称:Strategy意图策略模式是
    2023-07-02

    java设计模式之策略模式怎么实现

    这篇文章主要介绍了java设计模式之策略模式怎么实现,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。策略模式:策略模式是一种定义一系列算法的方法,算法完成的工作都是相同的工作,
    2023-05-31

    java策略设计模式怎么实现

    在Java中实现策略设计模式,可以按照如下步骤进行:1. 定义一个策略接口(或者抽象类),该接口包含多个具体策略类共同的方法。2. 创建具体的策略类,实现策略接口,并重写接口中的方法。每个具体策略类代表一个具体的策略实现。3. 在使用策略的
    2023-08-31

    Java策略模式的结构是怎样的

    本篇内容介绍了“Java策略模式的结构是怎样的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 策略模式是对算法的包装,是把使用算法的责任和算
    2023-06-04

    java 使用策略模式操作JDBC数据库

    java 使用策略模式操作JDBC数据库1:构造一个操作数据库的工具类,可以获得连接和释放连接public class DBUtil { private static Connection conn = null; static {
    2023-05-31

    怎么使用JavaScript策略模式校验表单

    小编给大家分享一下怎么使用JavaScript策略模式校验表单,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!javascript是一种什么语言javascript
    2023-06-14

    Java行为型设计模式之策略模式怎么实现

    本文小编为大家详细介绍“Java行为型设计模式之策略模式怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java行为型设计模式之策略模式怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.策略设计模
    2023-07-04

    Java中怎么用策略模式实现条件判断

    本文小编为大家详细介绍“Java中怎么用策略模式实现条件判断”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java中怎么用策略模式实现条件判断”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。定义策略模式定义了一系
    2023-06-29

    javascript设计模式中的策略模式怎么实现

    这篇文章主要讲解了“javascript设计模式中的策略模式怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript设计模式中的策略模式怎么实现”吧!一. 认识策略模式策略
    2023-06-26

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录