C++设计模式:策略模式(二)

1、定义与动机
  • 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化),该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)

  • 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都硬编码到对象中,将会使对象变得异常复杂;而且有时候支持不适用的算法也是一个性能负担(代码段过长)

  • 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

2、举例
  • 对于一个跨境电商的软件来说计算不同国家的税收、货币结算是一个非常常见的事情
  • 而通产来说每个国家的税的计算方式并不相同,每个国家都有其自己的税换算算法
  • 这里的设计也存在一定的门路,如果换成代码层面来看
2.1、结构化软件设计流程

这种做法很简单:

  • 首先定义一个枚举类,将不同国家的税率计算方式定义出来(这个可以不需要)只是为了使用方便
  • 然后定义销售订单类,里面定义计算税的方法,具体的实现通过大量的if-else if-else来具体调用
  • 对于这样的一个计算税的方法,calculate方法过于庞大,主要存在两个问题:
    • 违背开闭原则(OCR):当这个海外电商需要新增一个上线的国家,那么需要修改TaxBase枚举类,其次需要在计算方法里面增加这个国家的税计算方式,很明显违背修改关闭拓展开放的原则
    • 性能负担:其实这个软件在一个国家上线后大量的其他国家的税计算方式并不关心,但是在代码中强行硬编码写入!运行起来的代码段充斥着大量的无关代码!导致性能的下降
enum TaxBase{CN_Tax,                 // 国内税US_Tax,                 // 美国税DE_Tax                  // 德国税/*如果需要增加,需要在这里继续枚举的定义....JP_Tax,FR_Tax*/
};class SalesOrder{
private:TaxBase tax;
public:double calculateTax(){//...if(tax == CN_Tax){// CN*****}else if(tax == US_Tax){// US*****}else if(tax == DE_Tax){// DE*****}// 这里需要增加拓展国家税的计算方式}
};
2.2、策略模式
  • 策略模式:当代码中存在大量的if-else if-else或者switch-case时,就应该考虑使用策略模式来优化
  • 实现思路思考:
    • 首先定义一个计算税的抽象基类TaxStrategy
    • 对于不同的国家计算方式定义不同的类继承TaxStrategy基类,并且实现其计算calculateTax方法
    • 然后在需要使用计算的代码中聚合/组合一个基类TaxStrategy的指针,如果注入的方式初始化!
    • 最后在需要的地方通过基类指针TaxStrategy调用对应的不同国家的方法。
    • 核心点主要有几地方:
      • 所有国家的税收计算类都继承基类,并且实现基类的抽象方法
      • 在需要使用的地方定义基类对象的指针,通过注入的方式传入需要的子类对象(多态)
      • 最后调用方法通过虚函数表来调用实际传入对象的计算方法(动态绑定、晚绑定)
      • 策略模式提倡的互相替换在这里通过多态来实现,替换体现在实际传入初始化的对象到底是哪一个!
  • 这样做的好处:
    • 如果需要增加新的国家,可以看到大部分代码都是不用修改的,只需要扩展新的类即可
    • 性能的优化,实际说在使用的过程中只需要把需要的对象new出来即可
class TaxStrategy {
public:virtual double calculateTax() = 0;virtual ~TaxStrategy();
};class CNTax: public TaxStrategy{
public:double calculateTax() override {// 国内税计算}
};class USTax: public TaxStrategy{
public:double calculateTax() override {// 美国税计算}
};class DETax: public TaxStrategy{
public:double calculateTax() override {// 德国税计算}
};
class JPTax: public TaxStrategy{
public:double calculateTax() override {// 日本税计算}
};class SalesOrder{
private:TaxStrategy *taxStrategy;               // 基类指针
public:SalesOrder(TaxStrategy *_taxStrategy): taxStrategy(_taxStrategy){}virtual ~SalesOrder(){delete taxStrategy;taxStrategy = nullptr;}double calculate(){// ...// 还是动态绑定通过虚函数来调用实际的传入对象的calculateTax方法double val = taxStrategy->calculateTax();// ...return val;}
};

在这里插入图片描述

通过这个UML图可以看到TaxStrategy和SalesOrder是相对稳定的,而不稳定的是TaxStrategy的子类

3、总结
  • Strategy及其子类为组件提供了一系列的可重用的算法,从而可以使得类型在运行时方便地根据需要再各个算法之间进行切换

  • Strategy模式提供了用条件判断语句意外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式

  • 如果Strategy对象没有实例化变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。

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

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

相关文章

web安全学习笔记(6)

记一下第十节课的内容。 一.PHP语言中的if else判断 语法和c语言中非常类似,不再赘述,也可以使用if...elseif...elseif...else 1.True和False 2.,和 一个等号是赋值 两个等号是比较 三个等号是全等(内容相等,数…

OpenHarmony开发-系统烧录

本文详细介绍了烧录OpenHarmony系统到开发板的操作流程。从基础的硬件准备和软件环境设置入手,详细说明了如何配置开发环境、构建系统镜像等过程,详细描述了烧录过程中的关键步骤,以及如何使用专用工具将OpenHarmony系统镜像传输到开发板。同…

第十四届蓝桥杯大赛软件赛省赛

第十四届蓝桥杯大赛软件赛省赛 2.日期统计 小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的范围之内。 数组中的元素从左至右如下所示: 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 …

PyQt6实战6--高亮

PyQt6实战3--sql查询器-CSDN博客 在sql查询器的基础上添加了sql语法的高亮 运行效果: 代码: 只需要在原来的代码上添加一行 rightTopLayout QVBoxLayout()rightTopLayout.addWidget(QLabel("输入sql:"))self.sql QTextEdit() #加一行高亮&…

【踩坑日记】因不同系统换行符不同导致的文本读取结果不同的问题

文章目录 1 问题现象描述2 解决过程(点击直接跳到解决方法)3 原因解释4 如何避免踩坑4.1 格式转换4.2 格式查看 1 问题现象描述 起因是群友问了这么一个问题 确实很奇怪,按理说第二个printf不会完全不输出,于是想到,…

多线程学习-线程池

目录 1.线程池的作用 2.线程池的实现 3.自定义创建线程池 1.线程池的作用 当我们使用Thread的实现类来创建线程并调用start运行线程时,这个线程只会使用一次并且执行的任务是固定的,等run方法中的代码执行完之后这个线程就会变成垃圾等待被回收掉。如…

7.二叉树的遍历方式及二叉树习题

4.二叉树链式结构的实现 二叉树是: 空树 非空:根节点,根节点的左子树、根节点的右子树组成的。 4.1二叉树的遍历 4.2.1 前序、中序以及后序遍历 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前…

161 Linux C++ 通讯架构实战15,线程池代码分析

线程池应该使用的地方 和 epoll 技术结合 线程池代码处理数据的地方。 线程池分析: 线程池代码1 threadpool_create //Tencent8888 start threadpool_create函数的目的初始化线程池,对应的struct是 threadpool_t /* 1.先malloc整个线程池的大小 2.这里…

Memcached 教程之 PHP 连接 Memcached 服务(十)

PHP 连接 Memcached 服务 在前面章节中我们已经介绍了如何安装 Memcached 服务,接下来我们为大家介绍 PHP 如何使用 Memcached 服务。 PHP Memcache 扩展安装 PHP Memcache 扩展包下载地址:PECL :: Package :: memcache,你可以下载最新稳定…

Vuex(vue 项目中实现 频繁、大范围数据共享的技术方案)

参考文档(点击查看) 好处 1.数据的存取一步到位,不需层层传递 2.数据的流动非常清晰 3.存储在Vuex中的数据都是响应式的(数据更新后,使用数据的组件都会自动更新) Vuex基础配置 npm i vuex3.6.2state中用来存储数据&#xff0c…

2_5.Linux存储的基本管理

实验环境: 系统里添加两块硬盘 ##1.设备识别## 设备接入系统后都是以文件的形式存在 设备文件名称: SATA/SAS/USB /dev/sda,/dev/sdb ##s SATA, dDISK a第几块 IDE /dev/hd0,/dev/hd1 ##h hard VIRTIO-BLOCK /de…

BPMNJS 在原生HTML中的引入与使用

BPMNJS 在HTML中的引入与使用 在网上看到的大多是基于vue使用BPMN的示例或者教程,竟然没有在HTML使用的示例,有也是很简单的介绍核心库的引入和使用,并没有涉及到扩展库。于是简单看了下,真的是一波三折,坎坎坷坷。不…

Linux:权限篇

文章目录 前言1.用户2.文件的权限管理2.1 修改文件的权限2.2 修改文件的拥有者2.3 修改文件的所属组 3.file指令4.umask指令4.目录的权限管理总结 前言 Linux权限在两个地方有所体现,一种是使用用户:分为root超级用户员与普通用户。另一个是体现在文件的…

在Java中对SQL进行常规操作的通用方法

SQL通用方法 一、常规方法增删改查二、具体优化步骤1.准备工作2.getcon()方法,获取数据库连接对象3.closeAll()方法,关闭所有资源4.通用的增删改方法5.通用的查询方法6.动态查询语句 总结 一、常规方法增删改查 在常规方法中,我们在Java中对…

数据库排错记录

目录 一、 规范二、 优化查询1) 通过执行计划 三、 排查故障1) 网络断连2) 超时登录已断开3) 死锁4) 实例错误 一、 规范 尽量不要用select *,select 语句最好加上with(nolock)数据量大的表必须要有主键,可以是自增ID查询语句的条件里面的字段&#xff…

勒索病毒最新变种.rmallox勒索病毒来袭,如何恢复受感染的数据?

导言: 随着信息技术的飞速发展,网络安全问题日益突出,其中勒索病毒便是近年来备受关注的网络安全威胁之一。在众多勒索病毒中,.rmallox勒索病毒以其独特的传播方式和强大的加密能力,给广大用户带来了极大的困扰。本文…

11-pyspark的RDD的变换与动作算子总结

目录 前言 变换算子动作算子 前言 一般来说,RDD包括两个操作算子: 变换(Transformations):变换算子的特点是懒执行,变换操作并不会立刻执行,而是需要等到有动作(Actions)…

索引的概念

索引的概念    1.索引是一种可选的与表相关的数据库对象,用于提高数据的查询效率。    2.索引是一种有序的数据结构。    3.如果一个表没有创建索引,则对该表进行查询时需要进行全表扫描;如果创建了索引,则在有条件查询时…

thinkphp6入门(21)-- 如何删除图片、文件

假设文件的位置在 /*** 删除文件* $file_name avatar/20240208/d71d108bc1086b498df5191f9f925db3.jpg*/ function deleteFile($file_name) {// 要删除的文件路径$file app()->getRootPath() . public/uploads/ . $file_name; $result [];if (is_file($file)) {if (unlin…

C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测

C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测 目录 C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测效果一览基本介绍程序设计参考…