当前位置: 首页 > news >正文

23种设计模式之策略模式

一、概念

就是将一系列算法封装起来,并使它们之间相互替换。被封装起来的算法具有独立性外部不可改变其特性。
策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

二、应用场景

业务代码需要根据场景不同,切换不同的实现逻辑
代码中存在大量 if else 逻辑判断

三、结构

抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口,所有具体的策略类都要实现这个接口。环境(上下文)类Context 使用这个接口调用具体的策略类。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
环境(Context)类:用于配置一个具体的算法策略对象 ,维持一个策略接口类型的引用( Reference ),并且可以定义一个让接口 Strategy 的具体对象访问的接口。在简单情况下,Context 类可以省略。

四、示例

在这里插入图片描述

  1. 传统的实现方式:
    public Double calculationPrice(String type, Double originalPrice, int n) {//中级会员计费if (type.equals("intermediateMember")) {return originalPrice * n - originalPrice * 0.1;}//高级会员计费if (type.equals("advancePrimaryMember")) {return originalPrice * n - originalPrice * 0.2;}//普通会员计费return originalPrice;}

传统的实现方式,通过传统if代码判断。这样就会导致后期的维护性非常差。当后期需要新增计费方式,还需要在这里再加上if(),也不符合设计模式的开闭原则。

  1. 策略模式实现方式:

抽象类策略:

package StrategyExercise;public interface MemberStrategy {// 一个计算价格的抽象方法//price商品的价格 n商品的个数public double calcPrice(double price, int n);
}
**具体实现类:**
// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略//重写策略方法具体实现功能@Overridepublic double calcPrice(double price, int n) {return price * n;}
}
package StrategyExercise;// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{@Overridepublic double calcPrice(double price, int n) {double money = (price * n) - price * n * 0.1;return money;}
}package StrategyExercise;// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{@Overridepublic double calcPrice(double price, int n) {double money = price * n - price * n * 0.2;return money;}
}

上下文类(也叫做上下文类或环境类,起承上启下封装作用。)

package StrategyExercise;/*** 负责和具体的策略类交互* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。*/// 上下文类/环境类
public class MemberContext {// 用户折扣策略接口private MemberStrategy memberStrategy;// 注入构造方法public MemberContext(MemberStrategy memberStrategy) {this.memberStrategy = memberStrategy;}// 计算价格public double qoutePrice(double goodsPrice, int n){// 通过接口变量调用对应的具体策略return memberStrategy.calcPrice(goodsPrice, n);}
}

测试类

package StrategyExercise;// 测试类
public class Application {public static void main(String[] args) {// 具体行为策略MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy(); // 接口回调(向上转型)MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();// 用户选择不同策略MemberContext primaryContext = new MemberContext(primaryMemberStrategy);MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);MemberContext advanceContext = new MemberContext(advanceMemberStrategy);//计算一本300块钱的书System.out.println("普通会员的价格:"+ primaryContext.qoutePrice(300,1));// 普通会员:300System.out.println("中级会员的价格:"+ intermediateContext.qoutePrice(300,1));// 中级会员 270System.out.println("高级会员的价格:"+ advanceContext.qoutePrice(300,1));// 高级会员240}
}

测试结果

普通会员的价格:300.0
中级会员的价格:270.0
高级会员的价格:240.0

上述案例UML类图
在这里插入图片描述

五、优缺点

1、优点

  • 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  • 策略模式提供了管理相关的算法族的办法。
  • 策略模式提供了可以替换继承关系的办法。
  • 使用策略模式可以避免使用多重条件转移语句。

2、缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
  • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。

相关文章:

23种设计模式之策略模式

一、概念 就是将一系列算法封装起来,并使它们之间相互替换。被封装起来的算法具有独立性外部不可改变其特性。 策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算…...

不会做UI自动化测试?一起设计框架再实践吧

目的相信做过测试的同学都听说过自动化测试,而UI自动化无论何时对测试来说都是比较吸引人的存在。相较于接口自动化来说它可以最大程度的模拟真实用户的日常操作与特定业务场景的模拟,那么存在即合理,自动化UI测试自然也是广大测试同学职业道…...

数据分析实战项目3:RFM用户分群

目录1、RFM模型介绍2、Excel实际RFM划分案例3、RFM案例3.1 数据加载和基本信息查看3.2 数据预处理和RFM的初始值计算3.3 RFM区间和划分和分值计算3.4 RFM计算结果保存3.4.1 保存到excel3.4.2 保存到数据库3.5 RFM计算结果可视化3.6 结果分析(营销建议)3.…...

消息中间件概述

目录1.为什么学习消息队列2.什么是消息中间件3.消息队列应用场景3.1 应用解耦3.2 异步处理3.3 流量削峰3.4 什么是QPS,PV3.5 什么是PV,UV,PR4. AMQP 和 JMS4.1 AMQP4.2 JMS4.3. AMQP 与 JMS 区别5. 消息队列产品6. RabbitMQ6.1 RabbitMQ简介6.2 RabbitMQ 中的相关概…...

vue和js给后端接口返回的数据(如以json数据为元素的数组)添加新的json字段

文章目录vue和js给后端接口返回的数据(如以json数据为元素的数组)添加新的json字段1. res为后端接口的响应2. 获取后端接口返回的数据3. 向 tableData 添加字段3.1. 向 tableData 中添加一个新json元素( {"time", "2023-02-09"} )3.…...

负载均衡的方式

在业务初期,我们一般会先使用单台服务器对外提供服务。随着业务流量越来越大,单台服务器无论如何优化,无论采用多好的硬件,总会有性能天花板,当单服务器的性能无法满足业务需求时,就需要把多台服务器组成集…...

python(15)--函数设计

前言 函数是可重用的程序代码块。 函数的作用,不仅可以实现代码的复用,还可以保证修改函数的代码时,所有调用该函数的地方都能得到体现。目前我已知函数的作用是:对代码实现了封装、函数调用、传递参数、返回计算结果等。 正文 …...

手把手教你用Python做可视化数据,还能调节动画丝滑度

数据可视化动画还在用Excel做? 现在一个简单的Python包就能分分钟搞定! 而且生成的动画也足够丝滑,效果是酱紫的: 这是一位专攻Python语言的程序员开发的安装包,名叫Pynimate。 目前可以直接通过PyPI安装使用。 使用…...

湖南中创教育PMP项目管理——变更管理

【变更管理​】包括 一、如何理解需求变更 二、如何控制需求变更 三、项目变更管理流程 四、如何应对“奇葩”变更 一、如何理解需求变更: 1、项目中发生变更是正常现象,变更无法回避 2、哪里都可能出现变更,任何人都有权提出变更 3、…...

IC真题 —— 刷题记录(1)

引言 记录一些 我自己刷的 IC行业招聘真题,不是每题记录,只记录一些值得记录的,写下自己的看法。主要是一些数字IC行业题目,偏前端。 1、有一个逐次逼近型 8位A/D 转换器,若时钟频率为250KHz,完成一次转换…...

【C++入门】命名空间,输出输入,缺省参数,函数重载

文章目录命名空间C输入与输出缺省参数函数重载命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标 识符的名称进行本地化&#xff0…...

cmu 445 poject 2笔记

2022年的任务 https://15445.courses.cs.cmu.edu/fall2022/project2/ checkpoint 1,实现b树,读,写,删 checkpoint 2, 实现b树,迭代器,并发读写删 本文不写代码,只记录遇到的一些思维盲点 checkp…...

梅开二度的 axios 源码阅读,三千字详细分享功能函数,帮助扩展开发思维

前言 第一遍看 axios 源码,更多的是带着日常开发的习惯,时不时产生出点联想。 第二遍再看 axios 源码,目标明确,就是奔着函数来的。 当有了明确清晰的目标,阅读速度上来了,思绪也转的飞快。 按图索骥&a…...

vcs仿真教程

VCS是在linux下面用来进行仿真看波形的工具,类似于windows下面的modelsim以及questasim等工具,以及quartus、vivado仿真的操作。 1.vcs的基本指令 vcs的常见指令后缀 sim常见指令 2.使用vcs的实例 采用的是全加器的官方教程,首先介绍不使用…...

java 自定义json解析注解 复杂json解析 工具类

java 自定义json解析注解 复杂json解析 工具类 目录java 自定义json解析注解 复杂json解析 工具类1.背景2、需求-各式各样的json一、一星难度json【json对象中不分层】二、二星难度json【json对象中出现层级】三、三星难度json【json对象中存在数组】四、四星难度json【json对象…...

类的 6 个默认成员函数

文章目录一、构造函数1. 构造函数的定义2. 编译器生成的构造函数3. 默认构造函数4. 初始化列表5. 内置成员变量指定缺省值(C11)二、析构函数1. 析构函数的定义2. 编译器生成的析构函数3. 自己写的析构函数的执行方式三、拷贝构造函数1. C语言值传递和返回值时存在 bug2. 拷贝构…...

基于Verilog HDL的状态机描述方法

⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。 🔥文章和代码已归档至【Github仓库&#xf…...

6年软件测试经历:成长、迷茫、奋斗

前言 测试工作6年,经历过不同产品、共事过不同专业背景、能力的同事,踩过测试各种坑、遇到过各种bug。测试职场生涯积极努力上进业务和技术能力快速进步过、也有努力付出却一无所得过、有对测试生涯前景充满希望认为一片朝气蓬勃过、也有对中年危机思考不…...

OpenMMLab AI实战营第五次课程

语义分割与MMSegmentation 什么是语义分割 任务: 将图像按照物体的类别分割成不同的区域 等价于: 对每个像素进行分类 应用:无人驾驶汽车 自动驾驶车辆,会将行人,其他车辆,行车道,人行道、交…...

【软考】系统集成项目管理工程师(二十)项目风险管理

一、项目风险管理概述1. 风险概念2. 风险分类3. 风险成本二、项目风险管理子过程1. 规划风险管理2. 识别风险3. 实施定性风险分析4. 实施定量风险分析5. 规划风险应对6. 控制风险三、项目风险管理流程梳理一、项目风险管理概述 1. 风险概念 风险是一种不确定事件或条件,一旦…...

2017-PMLR-Neural Message Passing for Quantum Chemistry

2017-PMLR-Neural Message Passing for Quantum Chemistry Paper: https://arxiv.org/pdf/1704.01212.pdf Code: https://github.com/brain-research/mpnn 量子化学的神经信息传递 这篇文献作者主要是总结了先前神经网络模型的共性,提出了一种消息传递神经网络&am…...

Python:每日一题之全球变暖(DFS连通性判断)

题目描述 你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示: ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿…...

企业级安全软件装机量可能大增

声明 本文是学习大中型政企机构网络安全建设发展趋势研究报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 研究背景 大中型政企机构是网络安全保护的重中之重,也是国内网络安全建设投入最大,应用新技术、新产品最多的机构…...

为什么要用频谱分析仪测量频谱?

频谱分析仪是研究电信号频谱结构的仪器,用于信号失真度、调制度、谱纯度、频率稳定度和交调失真等信号参数的测量,可用以测量放大器和滤波器等电路系统的某些参数,是一种多用途的电子测量仪器。从事通信工程的技术人员,在很多时候…...

Python环境搭建、Idea整合

1、学python先要下载什么? 2、python官网 3、idea配置Python 4、idea新建python 学python先要下载什么? python是一种语言,首先你需要下载python,有了python环境,你才可以在你的电脑上使用python。现在大多使用的是pyt…...

HTTP请求返回304状态码以及研究nginx中的304

文章目录1. 引出问题2. 分析问题3. 解决问题4. 研究nginx中的3044.1 启动服务4.2 ETag说明4.3 响应头Cache-Control1. 引出问题 之前在调试接口时,代码总出现304问题,如下所示: 2. 分析问题 HTTP 304: Not Modified是什么意思? …...

【GD32F427开发板试用】使用Arm-2D显示电池电量

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:boc 【虽迟但到】 由于快递的原因,11月份申请的,12月1日才收到GD32F427开发板。虽然姗姗来迟,但也没有减少…...

TS第二天 Typesrcipt编译

文章目录自动编译tsconfig.json配置选项include 比较重要excludeextendsfilescompilerOptions 比较重要自动编译 手动模式:每次ts文件修改完,手动编译一次 tsc 01.ts监视模式:ts文件修改完,自动监视编译 tsc 01.ts -w编译所有文…...

基于C#制作一个飞机大战小游戏

此文主要基于C#制作一个飞机大战游戏,重温经典的同时亦可学习。 实现流程1、创建项目2、界面绘制3、我方飞机4、敌方飞机5、子弹及碰撞检测实现流程 1、创建项目 打开Visual Studio,右侧选择创建新项目。 搜索框输入winform,选择windows窗体…...

git修改历史提交(commit)信息

我们在开发中使用git经常会遇到想要修改之前commit的提交信息,这里记录下怎么使用git修改之前已经提交的信息。一、修改最近一次commit的信息 首先通过git log查看commit信息。 我这里一共有6次commit记录。 最新的commit信息为“Merge branch ‘master’ of https:…...

品牌理念设计企业网站建设/客户引流的最快方法是什么

Python版本: 3.6.0 一、添加Media Types Name:自定义的媒介名称 Type:Scipt 脚本 Scipt name : 脚本名称 Scipt parameters : 传递给脚本的参数。(该参数可以在后面的Actions部分自定义)。这里我们就使…...

制作视频模板/应用宝aso优化

宣传官网 xb.exrick.cn在线Demo xboot.exrick.cn开源版Github地址 github.com/Exrick/x-bo…开发文档 www.kancloud.cn/exrick/xboo…获取完整版 xpay.exrick.cn/pay?xboot JWT JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式&am…...

网站建设对数据库有何要求/如何做好网络营销

一、概述 taskdef是Ant内置任务,用于将任务定义添加到当前project中, 以便可以在当前project中使用此任务。taskdef是一种将adapter和adaptto属性分别设置为org.apache.tools.ant.TaskAdapter和org.apache.tools.ant.Task的typedef。typedef的特性同样适用于taskdef…...

网站建设速成/哪些平台可以打小广告

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…...

盐城网站推广哪家好/免费seo工具汇总

认识主机板煮 鸡板....咳!「主机板」(Motherboard)不算电脑里最先进的零组件,但绝对是塞最多东西的零组件。事实上,现在新的主机板简直像怪物,上面 可能有数十个长长短短、大大小小、圆的方的、各式各样的插…...

wordpress文章没缩略图/培训网站推广

现在的上班族,都是依靠电脑在办公的,所以每天接收到的电子文件有很多,这些都跟自己的工作息息相关,所以一般都是需要保存在电脑里面的,但是电脑就真的很安全吗?能确保数据的安全吗? 其实电脑虽然…...