项目优化之策略模式

目录

策略模式基本概念

策略模式的应用场景

实际项目中具体应用

项目背景:

策略模式解决方案:

计费模块策略模式简要代码


策略模式基本概念


        策略模式(Strategy Pattern) 是一种行为型设计模式,把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离,即算法本身和使用算法的客户端代码是解耦的。简单来说,策略模式就是定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式使得算法可独立于使用它的客户而变化。

策略模式的应用场景


策略模式在软件开发中有着广泛的应用场景,包括但不限于以下几种情况:
(1)多种算法的实现:当存在多种算法,而这些算法的实现又需要频繁地更换或扩展时,可以考虑使用策略模式。通过定义不同的策略类来实现不同的算法,客户端可以根据需要选择具体的策略。


(2)条件分支语句的替代:在程序中,如果存在大量的条件分支语句(如if-else或switch-case),并且这些条件分支语句的实现逻辑比较复杂或容易变化时,可以考虑使用策略模式来替代这些条件分支语句。通过定义不同的策略类来实现不同的分支逻辑,客户端可以根据条件选择具体的策略。


(3)算法与数据结构的分离:在某些情况下,我们可能需要将算法与数据结构进行分离,以便能够独立地修改或扩展它们。这时,可以使用策略模式来将算法封装成独立的策略类,从而实现算法与数据结构的分离。


(4)可配置的行为:在某些系统中,某些行为可能需要根据配置或用户的选择来改变。这时,可以使用策略模式来定义不同的策略类,并根据配置或用户的选择来选择具体的策略。

实际项目中具体应用

项目背景:

        在停车场项目中车辆的计费规则是一个剧烈变动的因素,在全国不同地区不同厂库计费规则各不相同,即使同一个厂库也随着发改委的文件需要时长修改;此外随着停车场软件的逐步迭代升级,现场升级软件又难免需要迁移计费规则,从而导致大量的迁移和编译工作,占用不少的研发资源。

策略模式解决方案:


        项目需要解决的问题主要是: 千变万化的收费规则接入(程序扩展性)和规则在不同版本之间迁移;

         针对规则的剧烈变化在计费模块中不同的计费规则采用策略模式独立继承策略抽象类独立编码,从而保证计费模块的封装性。对于规则在不同版本之间的迁移,可以采用Qt的插件将不同的计费策略编译为插件,便于适用不同版本的程序,关于插件参考Qt插件博客,此处着重介绍策略模式的使用。

计费模块策略模式简要代码

计费抽象策略接口定义:

//计费车辆相关信息
class PveInfo
{
public:int parkId;//车场IDint parkingType;//停车类型 固定、授权、新能源int vehicleType;//车辆类型 大型车 小型车 自定义类型车等int outOfDate;int plateColor;string plateNoStr;int inType;//入场类型string inTimeStr;string outTimeStr;int payRuleId;//结算,优惠,处理状态等其他信息/*...*/
};class CalcParkingFee
{
public:CalcParkingFee() = default;virtual ~CalcParkingFee() = default;virtual int calcFee(const PveInfo&) = 0;
};

具体计费策略继承实现

class OneTimeCalc :public CalcParkingFee
{
public:OneTimeCalc() = default;~OneTimeCalc() = default;int calcFee(const PveInfo&) override{//按次收费具体计费return 0;}
};//停车时长阶梯计费
class StageCalc :public CalcParkingFee
{
public:StageCalc() = default;~StageCalc() = default;int calcFee(const PveInfo&) override{return 0;}
};//日夜分时按次计费
class DayAndnightCalc :public CalcParkingFee
{
public:DayAndnightCalc() = default;~DayAndnightCalc() = default;int calcFee(const PveInfo&) override{return 0;}
};

计费引擎匹配策略类:

class CalcFeeEngine
{private:std::unique_ptr<CalcParkingFee> strategy;public:CalcFeeEngine(std::unique_ptr<CalcParkingFee> strategy): strategy(std::move(strategy)) {}void setStrategy(std::unique_ptr<CalcParkingFee> newStrategy) {strategy = std::move(newStrategy);}int calcFee(const PveInfo& pveInfo) const {return strategy->calcFee(pveInfo);}
};

计费单元计费示例

int CalcFeeUtil::calc(PveInfo& pveInfo)
{//根据车辆类型 停车类型等匹配计费规则if (0 == matchPayRule(pveInfo)){//处理pveInfo  减免 优惠券 折扣 节假日等 /*...*/CalcFeeEngine calcEngine(mapId2CalcObj[pveInfo.payRuleId]);return calcEngine.calcFee();}else{//...}
}

        通过策略模式优化车辆计费模块,使得计费规则策略独立于计费单元的,从而保证了计费单元的稳定性和计费规则的可扩展性;最终将具体的计费规则单独以插件的形式接入程序,从而保证不同项目不同版本的程序计费规则的开发和迁移独立于主程序,极大的节约了开发资源。

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

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

相关文章

学习虚幻C++开发日志——创建Selection Widget及其应用

教程视频&#xff1a;脚本冒险 - YouTube 前提&#xff1a;此代码运用到Common UI插件&#xff0c;需将其开启&#xff0c;以免后序编写产生未定义结构体的报错信息&#xff01; 用C进行UI绑定 创建继承于CommonUserWidget的类&#xff0c;此处命名为SelectionBase Select…

Kafka中的Topic和Partition有什么关系?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka中的Topic和Partition有什么关系&#xff1f;】面试题。希望对大家有帮助&#xff1b; Kafka中的Topic和Partition有什么关系&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Apache Kafka 中&#…

SpringBoot Maven 项目 pom 中的 plugin 插件用法整理

把 SpringBoot Maven 项目打包成 jar 文件时&#xff0c;我们通常用到 spring-boot-maven-plugin 插件。 前面也介绍过&#xff0c;在 spring-boot-starter-parent POM 和 spring-boot-starter POM 中都有插件的管理&#xff0c;现在我们就撸一把构建元素中插件的用法。 一、…

c和c++中为什么要防止头文件被重复包含!

在编程中&#xff0c;头文件就像一本工具书&#xff0c;它包含了函数、类、宏、全局变量等的定义和声明&#xff0c;供其他代码文件引用。想象一下&#xff0c;如果你在写一篇文章时&#xff0c;反复引用同一本工具书的内容&#xff0c;会发生什么情况呢&#xff1f; 1. 避免重…

django vue3实现大文件分段续传(断点续传)

前端环境准备及目录结构&#xff1a; npm create vue 并取名为big-file-upload-fontend 通过 npm i 安装以下内容"dependencies": {"axios": "^1.7.9","element-plus": "^2.9.1","js-sha256": "^0.11.0&quo…

MCP(Model Context Protocol)模型上下文协议 进阶篇3 - 传输

MCP 目前定义了两种标准的客户端-服务端通信传输机制&#xff1a; stdio&#xff08;标准输入输出通信&#xff09;HTTP with Server-Sent Events (SSE)&#xff08;HTTP 服务端发送事件&#xff09; 客户端应尽可能支持 stdio。此外&#xff0c;客户端和服务端也可以以插件方…

openai swarm agent框架源码详解及应用案例实战

文章目录 简介数据类型Agent类Response类Result类Swarm类run_demo_loop交互式会话 基础应用agent-handsofffunction-callingcontext_variablestriage_agent 高阶应用通用客服机器人(support bot)构建航班服务agent 参考资料 openai 在24年10月份开源了一个教育性质的多agents协…

【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 2:基础知识

目录 1 预热1.1 记号1.2 分类器计算过载问题 2 多头编码&#xff08;MHE&#xff09;2.1 标签分解2.2 多头组合&#xff08;Multi-Head Combination&#xff09; 论文&#xff1a;Multi-Head Encoding for Extreme Label Classification 作者&#xff1a;Daojun Liang, Haixia …

攻防世界 - Misc - Level 1 | 适合作为桌面

关注这个靶场的其它相关笔记&#xff1a;攻防世界&#xff08;XCTF&#xff09; —— 靶场笔记合集-CSDN博客 0x01&#xff1a;考点速览 想要通过本关&#xff0c;你需要掌握以下知识点&#xff1a; Stegolve 查看图片隐写内容。 了解 pyc 文件&#xff0c;并知道如何通过 Wi…

Unity 从零开始的框架搭建1-3 关于命令模式的一些思考

Unity 从零开始的框架搭建1-2 事件的发布-订阅-取消的小优化及调用对象方法总结[半干货]-CSDN博客 本人水平有限 如有不足还请斧正&#xff0c;该文章专栏是向QFrameWork作者凉鞋老师学习总结得来&#xff0c;吃水不忘打井人&#xff0c;不胜感激 关于此模式我曾实现过&#…

UVM :uvm_sequence_item property and methods

transaction是uvm_sequence_item的一个子类。 topic transaction介绍 uvm_sequence_item override Set_type_override:同类型替换 Set_inst_override:同例化替换

SpringBoot原理分析-1

SpringBoot原理分析 作为一个javaer&#xff0c;和boot打交道是很常见的吧。熟悉boot的人都会知道&#xff0c;启动一个springboot应用&#xff0c;就是用鼠标点一下启动main方法&#xff0c;然后等着就行了。我们来看看这个main里面。 SpringBootApplication public class E…

前端(API)学习笔记(CLASS 4):进阶

1、日期对象 日期对象&#xff1a;用来表示事件的对象 作用&#xff1a;可以得到当前系统时间 1、实例化 在代码中发现了new关键字&#xff0c;一般将这个操作称为实例化 创建一个时间对象并获取时间 获得当前时间 const datenew Date() 使用日志查看&#xff0c;得到的…

力扣刷题:二叉树OJ篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 1.单值二叉树&#xff08;1&#xff09;题目描…

4.1.2 栈和队列(二)

文章目录 队列的定义队列的基本运算队列的存储结构 队列的定义 队列先进先出&#xff0c;仅允许一端插入、一端删除 队尾(Rear)&#xff0c;插入 队头(Front)&#xff0c;删除 队列的基本运算 队列的基本运算 初始化空队列&#xff1a;initQueue(Q)判队空&#xff1a;isEmpty…

【HeadFirst系列之HeadFirst设计模式】第1天之HeadFirst设计模式开胃菜

HeadFirst设计模式开胃菜 前言 从今日起&#xff0c;陆续分享《HeadFirst设计模式》的读书笔记&#xff0c;希望能够帮助大家更好的理解设计模式&#xff0c;提高自己的编程能力。 今天要分享的是【HeadFirst设计模式开胃菜】&#xff0c;主要介绍了设计模式的基本概念、设计模…

Oracle数据库如何找到 Top Hard Parsing SQL 语句?

有一个数据库应用程序存在过多的解析问题&#xff0c;因此需要找到产生大量硬解析的主要语句。 什么是硬解析 Oracle数据库中的硬解析&#xff08;Hard Parse&#xff09;是指在执行SQL语句时&#xff0c;数据库需要重新解析该SQL语句&#xff0c;并创建新的执行计划的过程。这…

【GBT32960协议学习系列】GBT 32960协议的背景、目的和适用范围

GBT 32960协议的背景、目的和适用范围 1. GBT 32960协议的背景 GBT 32960是中国国家标准&#xff0c;全称为《电动汽车远程服务与管理系统技术规范》。该标准由中国国家标准化管理委员会发布&#xff0c;旨在规范电动汽车远程服务与管理系统的技术要求&#xff0c;确保电动汽车…

蓝桥杯备赛:C++基础,顺序表和vector(STL)

目录 一.C基础 1.第一个C程序&#xff1a; 2.头文件&#xff1a; 3.cin和cout初识&#xff1a; 4.命名空间&#xff1a; 二.顺序表和vector&#xff08;STL&#xff09; 1.顺序表的基本操作&#xff1a; 2.封装静态顺序表&#xff1a; 3.动态顺序表--vector&#xff1a;…

创建并配置华为云虚拟私有云

目录 私有云 创建虚拟私有云 私有云 私有云是一种云计算模式&#xff0c;它将云服务部署在企业或组织内部的私有基础设施上&#xff0c;仅供该企业或组织内部使用&#xff0c;不对外提供服务.私有云的主要特点包括&#xff1a; 私密性&#xff1a;私有云的资源&#xff08;如…