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

C++ 设计模式之策略模式

【声明】本题目来源于卡码网(题目页面 (kamacoder.com))

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】


【设计模式大纲】

【简介】什么是策略模式(第14种模式)

        策略模式是⼀种⾏为型设计模式,它定义了⼀系列算法(这些算法完成的是相同的⼯作,只是实现不同),并将每个算法封装起来,使它们可以相互替换,⽽且算法的变化不会影响使⽤算法的客户。
        举个例⼦,电商⽹站对于商品的折扣策略有不同的算法,⽐如新⽤户满减优惠,不同等级会员的打折情况不同,这种情况下会产⽣⼤量的if-else语句, 并且如果优惠政策修改时,还需要修改原来的代码,不符合开闭原则
        这就可以将不同的优惠算法封装成独⽴的类来避免⼤量的条件语句,如果新增优惠算法,可以添加新的策略类来实现,客户端在运⾏时选择不同的具体策略,⽽不必修改客户端代码改变优惠策略。


 【基本结构】

        策略模式包含下⾯⼏个结构:

  • 策略类Strategy : 定义所有⽀持的算法的公共接⼝。
  • 具体策略类ConcreteStrategy : 实现了策略接⼝,提供具体的算法实现。
  • 上下⽂类Context : 包含⼀个策略实例,并在需要时调⽤策略对象的⽅法。


 【简易实现】

        下面利用Java代码对策略模式的实现流程作以说明:

1. 抽象策略类

abstract class Strategy {// 抽象⽅法public abstract void algorithmInterface();
}

2. 具体策略类1

// 2. 具体策略类1
class ConcreteStrategyA extends Strategy {@Overridepublic void algorithmInterface() {System.out.println("Strategy A");// 具体的策略1执⾏逻辑}
}

3.具体策略类2

// 3. 具体策略类2
class ConcreteStrategyB extends Strategy {@Overridepublic void algorithmInterface() {System.out.println("Strategy B");// 具体的策略2执⾏逻辑}
}

4. 上下文类

// 4. 上下⽂类
class Context {private Strategy strategy;// 设置具体的策略public Context(Strategy strategy) {this.strategy = strategy;}// 执⾏策略public void contextInterface() {strategy.algorithmlnterface();}
}

5. 客户端代码

// 5. 客户端代码
public class Main{public static void main(String[] args) {// 创建上下⽂对象,并设置具体的策略Context contextA = new Context(new ConcreteStrategyA());// 执⾏策略contextA.contextInterface();Context contextB = new Context(new ConcreteStrategyB());contextB.contextInterface();u}
}

【使用场景】

        那什么时候可以考虑使⽤策略模式呢?

  • 当⼀个系统根据业务场景需要动态地在⼏种算法中选择⼀种时,可以使⽤策略模式。例如,根据⽤户的⾏为选择不同的计费策略。
  • 当代码中存在⼤量条件判断,条件判断的区别仅仅在于⾏为,也可以通过策略模式来消除这些条件语句。

        在已有的⼯具库中,Java 标准库中的 Comparator 接⼝就使⽤了策略模式,通过实现这个接⼝,可以创建不同的⽐较器(指定不同的排序策略)来满⾜不同的排序需求。


【编码部分】

1. 题目描述

        小明家的超市推出了不同的购物优惠策略,你可以根据自己的需求选择不同的优惠方式。其中,有两种主要的优惠策略: 

        1. 九折优惠策略:原价的90%。 

        2. 满减优惠策略:购物满一定金额时,可以享受相应的减免优惠。

具体的满减规则如下: 

        满100元减5元 

        满150元减15元 

        满200元减25元 

        满300元减40元

请你设计一个购物优惠系统,用户输入商品的原价和选择的优惠策略编号,系统输出计算后的价格。

2. 输入描述

        输入的第一行是一个整数 N(1 ≤ N ≤ 20),表示需要计算优惠的次数。 接下来的 N 行,每行输入两个整数,第一个整数M( 0 < M < 400) 表示商品的价格, 第二个整数表示优惠策略,1表示九折优惠策略,2表示满减优惠策略;

3. 输出描述

        每行输出一个数字,表示优惠后商品的价格;

4. C++ 编码实例

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file StrategyMode.hpp
* @brief 策略模式
* @autor 写代码的小恐龙er
* @date 2024/01/16
*/#include <iostream>
#include <string>
#include <vector>using namespace std;// 前置声明// 优惠策略的抽象接口类
class AbstractStrategy;// 优惠策略的具体实现类1 -- 打 九折 
class StrategyNineDiscount;// 优惠策略的具体实现类2 -- 满减
class StrategyFullOut;// 上下文类 -- 调用优惠策略类
class DiscountContext;// 类的定义// 优惠策略的抽象接口类
class AbstractStrategy
{
// 接口函数
public:// 传入参数为 商品的原始价格 返回值为优惠后的价格virtual int ApplyDiscount(int originalPrice) = 0;
};// 优惠策略的具体实现类1 -- 打 九折 
class StrategyNineDiscount : public AbstractStrategy
{
// 成员函数
public:StrategyNineDiscount(){}// 重载 优惠函数int ApplyDiscount(int originalPrice) override {return (int) (originalPrice * 0.9);}
};// 优惠策略的具体实现类2 -- 满减
class StrategyFullOut : public AbstractStrategy
{
// 成员数据
private:int _prices[4] = {100, 150, 200, 300};int _discounts[4] = {5, 15, 25, 40};
// 成员函数
public:StrategyFullOut(){}// 重载 优惠函数int ApplyDiscount(int originalPrice) override { // 从最大的优惠开始判断int length = sizeof(_prices) / sizeof(_prices[0]);for(int i = length - 1; i >= 0; i--){if(originalPrice >= _prices[i]){return originalPrice - _discounts[i];}}// 未达到满减优惠区间 return originalPrice;}
};// 上下文类 -- 调用优惠策略类
class DiscountContext
{
// 成员数据
private:AbstractStrategy *_strategy;
// 成员函数
public://通过传入策略基类来构造该类的实例DiscountContext(AbstractStrategy *strategy){this->_strategy = strategy;}    // 管理优惠函数int ApplyDiscount(int originalPrice){ if(_strategy == nullptr) return 0;else return _strategy->ApplyDiscount(originalPrice);}
};int main()
{// 优惠次数int discountNum = 0;// 输入std::cin >> discountNum;// 构造上下文管理类DiscountContext *discountContext = nullptr;// 构造抽象策略类AbstractStrategy *strategy = nullptr;// 遍历输入所有的价格for(int i = 0; i < discountNum; i++){// 原始价格 和 优惠策略int originalPrice = 0;int discountType = 0;// 输入 std::cin >> originalPrice >> discountType;// 根据打折类型来操作if(discountType == 1){// 构造具体的优惠类strategy = new StrategyNineDiscount();}else if(discountType == 2){// 构造具体的优惠类strategy = new StrategyFullOut();}else std::cout << originalPrice << endl;discountContext = new DiscountContext(strategy);// 使用优惠函数originalPrice = discountContext->ApplyDiscount(originalPrice);std::cout<< originalPrice << endl;}// 析构if(strategy != nullptr){delete strategy;strategy = nullptr;}if(discountContext != nullptr){delete discountContext;discountContext = nullptr;}return 0;
}


......

To be continued.

相关文章:

C++ 设计模式之策略模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【设计模式大纲】 【简介】什么是策略模式&#xff08;第14种模式&#xff09; 策略模式是⼀种⾏为型设计模式&…...

(202401)深度强化学习基础2:策略梯度

文章目录 前言策略梯度1 基于价值算法的缺点2 策略梯度算法3 REINFORCE算法本章小结 前言 感谢Datawhale成员的开源本次学习内容的文档地址为 第九章 策略梯度 策略梯度 这个章节会开始介绍基于策略梯度的算法。前面的算法都是针对“奖励”或者说“回报&#xff08;reward&a…...

bgp大AS小AS选路-联邦ebgp选路

效果图:R1 ping 通 R8 环回 R4的bgp路由表中5.5.5.5通过修改起源属性,下一跳R7变为R2, 即原本走下面R4-R7-R6-R5,改成R4-R3-R2-R5 R5效果图和R4类似(不放了)&#xff0c;R5的bgp路由表中4.4.4.4下一跳从R2优先改为R7优先(即原本走上面路R4-R3-R2-R5,改成下面路R4-R7-R6-R5),通…...

beego API 自动化文档

API 全局设置 必须设置在 routers/router.go 中&#xff0c;文件的注释&#xff0c;最顶部&#xff1a; // APIVersion 1.0.0 // Title mobile API // Description mobile has every tool to get any job done, so codename for the new mobile APIs. // Contact astaxiegmai…...

百度搜索Push个性化:新的突破

作者 | 通用搜索产品研发组 导读 本文简单介绍了百度搜索Push个性化的发展过程&#xff0c;揭示了面临的困境和挑战&#xff1a;如何筛选优质物料、如何对用户精准推荐等。我们实施了一系列策略方法进行突破&#xff0c;提出核心的解决思路和切实可行的落地方案。提升了搜索DAU…...

【Oracle】ORA-32017和ORA-00384错误处理

文章目录 【Oracle】ORA-32017和ORA-00384错误处理问题描述问题原因和解决测试验证 【声明】文章仅供学习交流&#xff0c;观点代表个人&#xff0c;与任何公司无关。 编辑|SQL和数据库技术(ID:SQLplusDB) 收集Oracle数据库内存相关的信息 【Oracle】ORA-32017和ORA-00384错误…...

MySQL三大日志

1. redo log 1.1 特点 InnoDB存储引擎独有物理日志&#xff0c;记录在数据页上做的修改让MySQL拥有了崩溃恢复能力&#xff0c;保证事务的持久性 1.2 刷盘时机 事务提交时log buffer 空间使用大约一半时事务日志缓冲区满InnoDB 定期执行检查点Checkpoint后台刷新线程&#…...

力扣每日一练(24-1-20)

大脑里的第一想法是排列组合&#xff0c;直接给出超级准确的最优解。 但不适用&#xff0c;hhh 只要连续的n个元素大于或者等于target就可以了 题目比自己想象的要好解决 解法是使用滑动窗口算法。这个算法的基本思想是维护一个窗口&#xff0c;使得窗口内的元素总和大于等于目…...

Pytest系列(2) - assert断言详细使用

前言 与unittest不同&#xff0c;pytest使用的是python自带的assert关键字来进行断言assert关键字后面可以接一个表达式&#xff0c;只要表达式的最终结果为True&#xff0c;那么断言通过&#xff0c;用例执行成功&#xff0c;否则用例执行失败 assert小栗子 想在抛出异常之…...

CodeWave智能开发平台--03--目标:应用创建--10初级采购管理系统总结

摘要 本文是网易数帆CodeWave智能开发平台系列的第14篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;实现一个完整的应用&#xff0c;本文主要完成10初级采购管理系统总结 CodeWave智能开发平台的14次接触 CodeWave参考资源 网易数帆CodeWave…...

外包干了4个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

图片批量建码怎么用?每张图片快速生成二维码

当我们需要给每个人分别下发对应的个人证件类图片信息&#xff0c;比如制作工牌、荣誉展示或者负责人信息展示时&#xff0c;现在都开始使用二维码的方法来展示员工信息。那么如何快速将每个人员的信息图片分别制作成二维码图片呢&#xff0c;最简单的方法就是使用图片批量建码…...

时间复杂度的排序

在计算机科学中&#xff0c;不同的算法有不同的时间复杂度。以下是一些常见的时间复杂度&#xff0c;并按照它们的增长速度从低到高排序&#xff1a; O(1) - 常数时间复杂度&#xff1a; 表示算法的执行时间是固定的&#xff0c;不随输入规模的增加而变化。例如&#xff0c;直接…...

js控制浏览器前进、后退、页面跳转

在JavaScript中&#xff0c;你可以使用 window 对象的 history 对象来控制浏览器的历史记录。以下是一些常用的方法&#xff1a; 前进和后退&#xff1a; window.history.forward(): 前进到历史记录中的下一个页面。window.history.back(): 返回历史记录中的上一个页面。window…...

【长文阅读】MAMBA作者博士论文<MODELING SEQUENCES WITH STRUCTURED STATE SPACES>-Chapter1

Gu A. Modeling Sequences with Structured State Spaces[D]. Stanford University, 2023. 本文是MAMBA作者的博士毕业论文&#xff0c;为了理清楚MAMBA专门花时间拜读这篇长达330页的博士论文&#xff0c;由于知识水平有限&#xff0c;只能尽自己所能概述记录&#xff0c;并适…...

Unity3D学习之UI系统——GUI

文章目录 1. 前言2. 工作原理和主要作用3. 基础控件3.1 重要参数及文本和按钮3.1.1 GUI 共同点3.1.2 文本控件3.1.3 按钮控件 3.2 多选框和单选框3.2.1 多选框3.2.2 单选框3.2.3 输入框3.2.4 拖动条 3.3 图片绘制和框3.3.1 图片3.3.2 框绘制 4 工具栏和选择网格4.1 工具栏4.2 选…...

用户ssh正确密码登陆均报错Permission denied, please try again.处理方法

我的一台虚拟机IP是&#xff1a;192.168.59.133任何服务器使用任何用户ssh均报错&#xff0c;甚至连自己都不能ssh自己。 不能使用任何工具连接上该服务器 使用ssh连接自己的127.0.0.1和localhost都权限拒绝错误 ssh报错如下 任何服务器ssh报错内容均一样&#xff1a;报错内…...

IO、NIO、IO多路复用

IO是什么&#xff1f; IO分为两类&#xff0c;它们之间是有区别的&#xff0c;而且有很大的区别&#xff1b;1. 文件系统的IO 也叫本地io&#xff0c;就是和磁盘或者外围存储设备进行读写操作&#xff0c;外围设备有USB、移动硬盘等等&#xff1b;2. 网络的IO 将数据发送给对方…...

探索FTP:原理、实践与安全优化

引言 在正式开始讲解之前&#xff0c;首先来了解一下文件存储的类型有哪些。 DAS、SAN和NAS是三种不同的存储架构&#xff0c;分别用于解决不同场景下的数据存储需求。 DAS (Direct Attached Storage 直接附加存储)&#xff1a;DAS 是指将存储设备&#xff08;如硬盘&#x…...

git中的语法和术语含义

目录 第一章、git常用术语1.1&#xff09;文件状态1.2&#xff09;git常用术语的含义 第二章、git文件状态解析2.1&#xff09;从git init开始&#xff1a;Untracked&#xff08;未跟踪&#xff09;2.2&#xff09;git add fileName后&#xff1a;Staged&#xff08;已暂存&…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...