设计模式之策略模式_入门

前言

        最近接触了优惠券相关的业务,如果是以前,我第一时间想到的就是if_else开始套,这样的话耦合度太高了,如果后期添加或者删除优惠券,必须直接修改业务代码,不符合开闭原则,这时候就可以选择我们的策略模式(Strategy Pattern)实现解耦,很好的解决上述问题,消除 if-else、switch 多重判断 可以有效应对代码的复杂性,十分优雅!

概念引入

         和上期的建造者模式类似,策略模式也有三个重要元素:

  1. 环境类:用于与策略接口交互的类。
  2. 策略接口:定义所有支持的算法的公共接口。
  3. 具体策略类:实现策略接口的具体算法。

具体案例(针对优惠券的案例)

        我们都知道不同优惠券有不同的优惠力度,非常契合策略模式本案例将结合策略模式和Spring特性来展示: 

        1.创建优惠券的策略接口 

/*
* 优惠券就是一个很好的策略模式的案例
* */
public interface DiscountStrategy {//优惠券折扣就可以抽象到接口中Double discount(Double price);//用于标识不同的折扣力度String mark();
}

        我们通过接口来管理优惠券,内部有负责折扣的抽象方法,具体折扣计算由实现类各自负责;还有负责标识的 mark方法。

        2.优惠券的具体实现类

/** 八折的折扣类,首先要实现之前的折扣接口,然后重写方法* 利用Spring的特性,将折扣实现类注入IOC容器* */@Component
public class Discount8Strategy implements DiscountStrategy{//8折折扣方法@Overridepublic Double discount(Double price) {return price*0.8;}@Overridepublic String mark() {return "1";}
}/** 九折的折扣类,首先要实现之前的折扣接口,然后重写方法* 利用Spring的特性,将折扣实现类注入IOC容器* */@Component
public class Discount9Strategy implements DiscountStrategy{//9折折扣方法@Overridepublic Double discount(Double price) {return price*0.9;}@Overridepublic String mark() {return "2";}
}

         这里我添加了两种折扣类,分别是8折和9折,同时利用了@Component将二者注入到Spring的IOC容器中,后续将配合Spring完成整个策略模式的实现

         3.优惠券工厂+Spring生命周期使用

/** 这里利用Spring的生命周期,实现InitializingBean方法,在bean初始化这一个阶段做一些处理,实现策略模式* */
@Component
public class DiscountStrategyFactory implements InitializingBean {//获取到ApplicationContext的实例,可以通过这个获取到想要的类实例@Autowiredprivate ApplicationContext applicationContext;//用来真正存储 (折扣力度标识,对应折扣实例)public final HashMap<String,DiscountStrategy> discountStrategies = new HashMap<>();//根据标识的mark选择对应的折扣实例,后续可以进行折扣public DiscountStrategy chooseDiscount(String mark){return discountStrategies.get(mark);}@Overridepublic void afterPropertiesSet() throws Exception {//因为到AfterPropertiesSet这个方法的时候,当前Bean的属性已经设置完成,所以我们可以获取到DiscountStrategy接口的实现类//利用Map这个数据类型,完成策略模式//使用了GetBeansOfType方法直接返回map类型。key是类的名字,value是对应的实例Map<String,DiscountStrategy> discountStrategyMap = applicationContext.getBeansOfType(DiscountStrategy.class);//利用stream流的方式遍历,扩充discountStrategiesdiscountStrategyMap.forEach((key,value)-> discountStrategies.put(value.mark(),value));}
}

        这里策略工厂类实现了InitializingBean接口,是利用了Spring生命周期中的AfterPropertiesSet方法,也就是在Bean初始化后这一个阶段。首先注入ApplicationContext实例,然后利用它调用GetBeanOfType得到(类名,对应实例)这一个Map对象,再利用Stream流进行处理得到了一个Key是mark,value是对应折扣实例的一个map,后续我们就可以使用这个map进行策略模式的使用

        4.具体使用

        折扣成功,这样业务中就可以利用类似的方式处理优惠券,是不是比if_else更加优雅,同时,后期遇到增删改的情况,是不是就符合了开闭原则。 

总结 

         入门了策略模式,我们最后看看他的一些优势:

  • 封装性:策略模式通过将算法封装在独立的类中,使得算法的变化不会影响到使用算法的客户端。
  • 可替换性:可以在运行时选择不同的算法来执行,而不需要修改客户端的代码。
  • 可扩展性:新增算法时,只需新增一个具体的策略类即可,符合开闭原则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/49192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【TypeScript 一点点教程】

文章目录 一、开发环境搭建二、基本类型2.1 类型声明2.2 基本类型 三、编译3.1 tsc命令3.2 tsconfig.json3.2.1 基本配置项includeexcludeextendsfiles 3.2.2 compilerOptions编译器的配置项 四、面向对象4.1 类4.2 继承4.3 抽象类4.4 接口 一、开发环境搭建 下载Node.js《Nod…

usb pd message结构解析

usb pd 3.1规范定义了三种类型的消息: •简短的控制消息&#xff0c;用于管理端口伙伴之间的消息流或交换不需要额外数据的消息。控制消息的长度为16位。 •用于在一对端口伙伴之间交换信息的数据消息。数据报文的长度范围是48 ~ 240位。 有三种类型的数据消息: ▪那些用于暴露…

【区块链+绿色低碳】双碳数字化管控平台 | FISCO BCOS应用案例

地方政府、园区及企业实现“双碳”目标过程中存在一些挑战与难点&#xff1a; 1. 管理者难以掌握完整、准确、全面的碳排放数据进行科学决策&#xff1a;由于碳排放核算需要对数据的来源、核算方法 的规范性和采集方法的科学性有严格要求&#xff0c;当前面临碳排放数据数据采…

中国一汽发布“一汽●北斗云工作台” 意在推动企业数智化转型

“一汽●北斗云工作台”已经实现100%自主可控&#xff0c;覆盖企业全价值链、全体系、全过程、全岗位的工作需求。目前一汽2.3万个业务单元实现线上作业&#xff0c;产品开发效率提升30%&#xff0c;订单交付周期缩短25%以上。”7月17日&#xff0c;中国第一汽车集团有限公司&a…

electron 网页TodoList工具打包成win桌面应用exe

参考&#xff1a; electron安装&#xff08;支持win、mac、linux桌面应用&#xff09; https://blog.csdn.net/weixin_42357472/article/details/140643624 TodoList工具 https://blog.csdn.net/weixin_42357472/article/details/140618446 electron打包过程&#xff1a; 要将…

【吊打面试官系列-ZooKeeper面试题】Zookeeper 的典型应用场景

​大家好&#xff0c;我是锋哥。今天分享关于 【Zookeeper 的典型应用场景 】面试题&#xff0c;希望对大家有帮助&#xff1b; Zookeeper 的典型应用场景 Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架&#xff0c;开发人员可以使用它来进行分布式数据的发布…

学习React(状态管理)

随着你的应用不断变大&#xff0c;更有意识的去关注应用状态如何组织&#xff0c;以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中&#xff0c;你将学习如何组织好状态&#xff0c;如何保持状态更新逻辑的可维护性&#xff0c;以及如何…

基于自组织映射的检索增强生成

大量数据用于训练大型语言模型 (LLM)&#xff0c;该模型包含数百万和数十亿个模型参数&#xff0c;目的是生成文本&#xff0c;例如文本补全、文本摘要、语言翻译和回答问题。虽然 LLM 从训练数据源中开发知识库&#xff0c;但总有一个训练截止日期&#xff0c;在此日期之后 LL…

java jts 针对shp含洞多边形进行三角剖分切分成可行区域

前言 java jts 提供了Delaunay三角剖分的相关方法,但是该方法不考虑含洞的多边形的。虽然 jts 的 ConformingDelaunayTriangulationBuilder 类可以通过提供线段约束的方式防止切割到洞内&#xff0c;但是仅支持最多99条线段&#xff0c;虽然可以通过重写破除99条线段的约束&am…

Java——————接口(interface) <详解>

1.1 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本电脑上的USB接口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘...所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff…

OS Copilot初体验的感受与心得

本文介绍体验操作系统智能助手OS Copilot后&#xff0c;个人的一些收获、体验等。 最近&#xff0c;抽空体验了阿里云的操作系统智能助手OS Copilot&#xff0c;在这里记录一下心得与收获。总体观之&#xff0c;从个人角度来说&#xff0c;感觉这个OS Copilot确实抓住了不少开发…

EasyMedia转码rtsp视频流flv格式,hls格式,H5页面播放flv流视频

EasyMedia转码rtsp视频流flv格式&#xff0c;hls格式 H5页面播放flv流视频 文章最后有源码地址 解决海康视频播放视频流&#xff0c;先转码后自定义页面播放flv视频流 先看效果&#xff0c;1&#xff0c;EasyMedia自带的页面&#xff0c;这个页面二次开发改动页面比较麻烦 …

张高兴的 MicroPython 入门指南:(三)使用串口通信

目录 什么是串口使用方法使用板载串口相互通信 硬件需求电路代码使用板载的 USB 串口参考 什么是串口 串口是串行接口的简称&#xff0c;这是一个非常大的概念&#xff0c;在嵌入式中串口通常指 UART(Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发器)。…

初识c++(string和模拟实现string)

一、标准库中的string类 string类的文档介绍&#xff1a;cplusplus.com/reference/string/string/?kwstring 1、auto和范围for auto&#xff1a; 在早期C/C中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量&#xff0c;后来这个 不重…

Cannot perform upm operation: connect ETIMEDOUT 34.36.199.114:443 [NotFound]

版本&#xff1a;Unity 2018 Windows 问题&#xff1a;打开 Package Manager&#xff0c;加载报错 尝试解决&#xff1a; 删除项目文件里的Packages下的mainfest.json文件&#xff0c;然后重新打开项目&#xff08;X&#xff09;重新登录 Unity 账号&#xff08;X&#xff09…

Kotlin 协程 — 基础

Kotlin 协程 — 基础 协程已经存在一段时间了&#xff0c;关于它的各种文章也很多。但我发现想要了解它还比较费时&#xff0c;所以我花了一段时间才真正理解了协程的基础知识以及它的工作原理。因此&#xff0c;我想分享一些我理解到的内容。 什么是协程&#xff1f; 协程代表…

vue项目实战速查记录

1.图片下载到本地 2.本地静态文件访问 3.元素大小相同,相互覆盖 1.图片下载到本地 实现原理:创建a标签,利用a标签下载属性. download(){const link document.createElement(a);link.href "图片地址";link.setAttribute(download, name);document.body.ap…

读论文《Hi-Net: Hybrid-fusion Network for Multi-modalMR Image Synthesis》

论文题目&#xff1a;Hi-Net:用于多模态磁共振图像合成的混合融合网络 论文地址&#xff1a;arxiv 项目地址&#xff1a;github 原项目可能在训练的时候汇报version的错&#xff0c;这是因为生成器和辨别器的优化有些逻辑错误&#xff0c;会改的话多加一个生成操作可以解决&…

React 学习——条件渲染、遍历循环、事件绑定

React特点&#xff1a; 声明式的设计高效&#xff0c;采用虚拟DOM来实现DOM的渲染&#xff0c;最大限度减少DOM的操作灵活&#xff0c;跟其他库灵活搭配使用JSX&#xff0c;俗称JS里面写HTML&#xff0c;JavaScript语法的扩展组件化&#xff0c;模块化&#xff0c;代码容易复用…

pdf的下载,后端返回工作流,前端进行转换

前端将后端返回的工作流进行转换 项目中接触到了pdf的下载和预览的功能&#xff0c;记录一下~ 这里pdf的下载和预览的接口&#xff0c;后端返回的数据结构与其他的接口返回的数据结构有点不同&#xff0c;是直接返回的工作流&#xff0c;在控制台接口的响应预览内容大致是这样…