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

大话设计模式解读02-策略模式

本篇文章,来解读《大话设计模式》的第2章——策略模式。并通过Qt和C++代码实现实例代码的功能。

1 策略模式

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法

策略模式的特点:

  • 定义了一组算法(业务规则)
  • 封装了每个算法
  • 这一类的算法可互换代替

策略模式的组成:

  • 抽象策略角色(策略类): 通常由一个接口或者抽象类实现
  • 具体策略角色:包装了相关的算法和行为
  • 环境角色(上下文):持有一个策略类的引用(或指针),最终给客户端调用

策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

2 收银软件实例

题目:做一个商场收银软件,营业员根据用户所购买商品的单价数量,向客户收费

我们联想策略模式,对于收费行为,在不同的场景中(正常收费、打折收费、满减收费),对应不同的算法(或称策略)实现。

下面先来看版本一,还未使用策略模式,仅实现基础的收费计算。

2.1 版本一:基础收费

这里使用Qt设计一个收费系统的界面,每次可以输入单价和数量,点确定按钮之后,会在信息框中展示此次的合计价格,支持多个商品的多次计算,多次计算的总价在最下面的总计栏中展示。

对应的代码实现如下:

  • on_okBtn_clicked 为Qt点击确定按钮后的槽函数:该函数实现为,此次的价格合计等于价格x数量,多次的价格累加是总计价格。
  • on_resetBtn_clicked 为Qt点击重置按钮后的槽函数:该函数实现为,清空相关的显示和各种数据
void Widget::on_okBtn_clicked()
{// 此次的价格合计:价格*数量float thisPrice = ui->priceEdit->text().toFloat() * ui->numEdit->text().toInt();// 总计m_fTotalPrice += thisPrice;// 窗口中展示明细ui->showPanel->append("price:" + ui->priceEdit->text()+ ", num:" + ui->numEdit->text()+ " -> (" + QString::number(thisPrice) + ")");// 显示总计ui->totalShow->setText(QString::number(m_fTotalPrice));
}void Widget::on_resetBtn_clicked()
{m_fTotalPrice = 0;ui->showPanel->clear();ui->totalShow->clear();ui->priceEdit->clear();ui->numEdit->clear();
}

实际的演示效果如下,仅实现单价x数量功能:

如果在此基础上,需要增加打折收费功能,需要怎么做呢?下面来看版本二。

2.2 版本二:增加打折

对于打折功能,在界面上,只需要增加一个打折率的下拉框即可,然后在计算公式上在加一步乘以打折率即可,代码改动不大:

void Widget::on_okBtn_clicked()
{// 根据下拉框获取对应的打折率float rebate = 1.0;if (ui->calcSelect->currentIndex() == 1) rebate = 0.8;else if (ui->calcSelect->currentIndex() == 2) rebate = 0.7;else if (ui->calcSelect->currentIndex() == 3) rebate = 0.5;// 此次的价格合计:价格*数量*打折率float thisPrice = ui->priceEdit->text().toFloat() * ui->numEdit->text().toInt() * rebate;// 总计m_fTotalPrice += thisPrice;// 窗口中展示明细ui->showPanel->append("price:" + ui->priceEdit->text()+ ", num:" + ui->numEdit->text()+ ", rebate:" + QString::number(rebate)+ " -> (" + QString::number(thisPrice) + ")");// 显示总计ui->totalShow->setText(QString::number(m_fTotalPrice));
}

演示效果如下,可以支持正常收费、八折收费、七折收费和五折收费。

目前看起来代码也还可以,但如果此时需要增加满减活动呢?比如满300减100这种。

因为满减这种方式,不像打折那样简单的乘以一个打折率就行了,它需要两个参数,**满减的价格条件,**的,满减的优惠值,,对于满300减100的方式,如果是700,满足了2次,就要减200了,这种计算方式需要单独再写一套计算逻辑。

下面来看版本三是如何实现的。

2.3 版本三:简单工厂

联想上次介绍的简单工厂模式,对于目前收费的需求,实际可以将其分类三类:

  • 正常收费类:不需要参数
  • 打折收费类:需要1个参数(打折率)
  • 满减收费类(返利收费类):需要2次参数(满减的价格条件的满减的优惠值)

因此,可以将这3钟方式分别封装为单独的收费类,并通过简单工厂的方式,在不同的收费需求下,实例化对应的收费计算对象,进行收费的计算。

2.3.1 收费类相关代码

对应的代码如下,设计了现金收费类CashSuper以及对应的具体子类:

  • 正常收费类:CashNormal,将原价原路返回
  • 打折收费类:CashRebate,初始化时输入打折率,计算时返回打折后的价格
  • 返利收费类:CashReturn,初始化时输入满减的条件和满减的值,计算时返回满减后的值
// 现金收费类
class CashSuper
{
public:virtual float acceptCash(float money){return money;}
};// 正常收费类
class CashNormal : public CashSuper
{
public:// 原价返回float acceptCash(float money){return money;}
};// 打折收费类
class CashRebate : public CashSuper
{
private:float m_fMoneyRebate = 1.0;public:// 初始化时输入打折率CashRebate(float rebate){m_fMoneyRebate = rebate;}// 返回打折后的价格float acceptCash(float money){return money * m_fMoneyRebate;}
};// 返利收费类
class CashReturn : public CashSuper
{
private:float m_fMoneyCondition = 0;float m_fMoneyReturn    = 0;
public:// 初始化时输入满减的条件和满减的值CashReturn(float moneyCondition, float moneyReturn){m_fMoneyCondition = moneyCondition;m_fMoneyReturn    = moneyReturn;}public:// 返回满减后的值(满足满减倍数,按倍数满减)float acceptCash(float money){float result = money;if (money >= m_fMoneyCondition){result -= ((int) money / (int) m_fMoneyCondition) * m_fMoneyReturn;}return result;}
};//现金收费工厂类
class CashFactory
{
public:CashSuper *createCashAccept(int combIdx) // 参数为下拉列表中的索引{CashSuper *pCS = nullptr;switch (combIdx){case 0: // "正常收费"{pCS = (CashSuper *)(new CashNormal());break;}case 1: // "打8折"{pCS = (CashSuper *)(new CashRebate(float(0.8)));break;}case 2: // "满300返100"{pCS = (CashSuper *)(new CashReturn(float(300), float(100)));break;}default:break;}return pCS;}
};

2.3.2 Qt界面上点击确定的槽函数的修改

Qt界面上点击确定,客户端的处理逻辑如下:

  • 计算此次的价格原价:价格x数量
  • 根据下拉框当前选择的策略,获取对应的索引值,目前代码中写了3种:
    • 索引0:正常收费
    • 索引1:打8折
    • 索引2:满300返100
  • 调用现金计算工厂,传入索引值,实例化对应的现金计算对象
  • 调用现金计算对象,得到此次的计算结果,展示在窗口明细中
  • 计算总计值,显示在总计框
void Widget::on_okBtn_clicked()
{// 此次的价格原价:价格*数量float thisPrice = ui->priceEdit->text().toFloat() * ui->numEdit->text().toInt();// 下拉框不同计算策略的索引值int idx = ui->calcSelect->currentIndex();// 现金计算工厂CashFactory cashFactory;CashSuper *pCS = cashFactory.createCashAccept(idx);if (pCS != nullptr){// 传入原价,根据结算规则,得到计算后的实际价格thisPrice = pCS->acceptCash(thisPrice);delete pCS;}// 总计m_fTotalPrice += thisPrice;// 窗口中展示明细ui->showPanel->append("price:" + ui->priceEdit->text()+ ", num:" + ui->numEdit->text()+ ", method:" +  ui->calcSelect->currentText()+ " -> (" + QString::number(thisPrice) + ")");// 显示总计ui->totalShow->setText(QString::number(m_fTotalPrice));
}

演示效果如下,可以支持正常收费、八折收费、满300减100收费。

上述代码,使用了简单工厂模式后,如果再需要增加一种新类型的促销手段,比如满100元则有10个积分,则只需要再增加一个现在收费类即可,接收2个参数(满足积分的条件和对应的积分值),继承于CashSuper类。

不过,虽然简单工厂模式实现了对不同的收费计算对象的创建管理,但对于本案例,商场可能经常更改打折的额度和返利额度,而每次维护或扩展收费方式都要改动这个工厂,然后代码需要重新编译部署,好像不是一种很好的方式。

下面来看版本四是如何实现的。

2.4 版本四:策略模式

版本四用到了本篇的主题——策略模式。

策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

对于本例,商场的促销手段:打折、返利这些,对应的就是算法。

用工厂来生成算法对象,本身也没有问题,但算法只是一种策略,而这些策略是随时可能互相替换的,这就是变化点。

策略模式的作用就是来封装变化点,设计的UML类图如下,与简单工厂的主要区别是将简单工厂类换成了上下文类

  • 上下文类,或称环境类,维护对具体策略的引用
  • 现金收费类,在这里对应的是策略类(父类)
  • 3种具体收费类,在这里对应的是具体的策略类(子类)

策略模式和简单工厂模式初看可能比较像,下面来看下代码实现的区别。

2.4.1 现金收费上下文类

收费类相关代码。相比较版本三,收费类和具体的收费类都不需要动,只需要把简单工厂类改为现金收费上下文类即可

现金收费上下文类有一个CashSuper的指针,实现对具体策略的引用

在初始化CashContext时,传入CashSuper的指针的指针,通过其提供的GetResult方法,可以得到其算法的计算结果。

这里的GetResult方法,调用的是具体策略的acceptCash方法。

//现金收费上下文类
class CashContext
{
private:CashSuper *m_pCS = nullptr;public:CashContext(CashSuper *pCsuper){m_pCS = pCsuper;}~CashContext(){if (m_pCS) delete m_pCS;}float GetResult(float money){return m_pCS->acceptCash(money);}
};

2.4.2 Qt界面上点击确定的槽函数的修改

Qt界面上点击确定,客户端的处理逻辑如下:

  • 计算此次的价格原价:价格x数量
  • 根据下拉框当前选择的策略,获取对应的索引值(0:正常收费,1:打8折,2:满300返100)
  • 然后将具体的算法类作为参数来创建一个上下文类
  • 再调用上下文类的GetResult方法,得到此次的计算结果,展示在窗口明细中
  • 计算总计值,显示在总计框
void Widget::on_okBtn_clicked()
{// 此次的价格原价:价格*数量float thisPrice = ui->priceEdit->text().toFloat() * ui->numEdit->text().toInt();// 下拉框不同计算策略的索引值int idx = ui->calcSelect->currentIndex();CashContext *pCC = nullptr;switch (idx){case 0: // "正常收费"{pCC = new CashContext(new CashNormal());break;}case 1: // "打8折"{pCC = new CashContext(new CashRebate(float(0.8)));break;}case 2: // "满300返100"{pCC = new CashContext(new CashReturn(float(300), float(100)));break;}default:break;}// 计算后的价格if (pCC != nullptr){// 传入原价,根据结算规则,得到计算后的实际价格thisPrice = pCC->GetResult(thisPrice);delete pCC;}// 总计m_fTotalPrice += thisPrice;// 窗口中展示明细ui->showPanel->append("price:" + ui->priceEdit->text()+ ", num:" + ui->numEdit->text()+ ", method:" +  ui->calcSelect->currentText()+ " -> (" + QString::number(thisPrice) + ")");// 显示总计ui->totalShow->setText(QString::number(m_fTotalPrice));
}

该代码的演示效果和版本三的一样,这里不再贴图。

下面再来分析下版本四的策略模式和版本三的简单工厂模式的区别:

  • 简单工厂模式:通过简单工厂来得到具体的计算对应对象,调用具体对象的acceptCash方法得到结果。
  • 策略模式:通过上下文类来维护对具体策略的引用,调用上下文类的GetResult方法得到结果(本质也是调用其维护的具体策略的acceptCash方法)。

对比发现,两种模式区别就在于;

  • 简单工厂模式是,根据你的需求,给你创建一个对应的收费计算对象,后续的收费计算你和这个对象来对接即可。
  • 而策略模式是,根据你的需求,上下文类帮你和具体的策略对象对接,你需要计算时,仍然通过上下文类的接口获取即可。

对于版本四的代码,Qt界面上客户端的处理代码又变得复杂了,如何将客户端的那些判断逻辑移走呢?下面来看版本五。

2.5 版本五:策略模式+简单工厂

版本四的代码,CashContext上下文类在初始化时,接收的参数是具体的策略类的指针。

在版本五中,将参数改为Qt界面收费类型下拉框的索引值,然后在CashContext内部,根据索引值,利用简单工厂模式,CashContext自己创建对应的策略对象,代码如下;

2.5.1 在策略模式内加入简单工厂

//现金收费上下文类
class CashContext
{
private:CashSuper *m_pCS = nullptr;public:CashContext(int combIdx){switch (combIdx){case 0: // "正常收费"{m_pCS = (CashSuper *)(new CashNormal());break;}case 1: // "打8折"{m_pCS = (CashSuper *)(new CashRebate(float(0.8)));break;}case 2: // "满300返100"{m_pCS = (CashSuper *)(new CashReturn(float(300), float(100)));break;}default:break;}}~CashContext(){if (m_pCS) delete m_pCS;}float GetResult(float money){if (m_pCS){return m_pCS->acceptCash(money);}return money;}
};

2.5.2 Qt界面上点击确定的槽函数的修改

Qt界面上点击确定,客户端的处理逻辑如下:

  • 计算此次的价格原价:价格x数量
  • 根据下拉框当前选择的策略,获取对应的索引值(0:正常收费,1:打8折,2:满300返100)
  • 然后将索引值作为参数来创建一个上下文类
  • 再调用上下文类的GetResult方法,得到此次的计算结果,展示在窗口明细中
  • 计算总计值,显示在总计框

可以看到如下代码中,版本五的Qt确定按钮的逻辑,又变得清爽起来。

但实际上,只是把这部分判断的代码移动到了CashContext中,如果后续需要新增一种算法,还是要修改CashContext中的判断的,但有需求就会有修改,任何需求的变更都是有成本的,只是变更成本高低的不同,继续降低目前CashContext的修改成本,可以利用反射技术,这在后续介绍抽象工厂模式时会提到。

void Widget::on_okBtn_clicked()
{// 此次的价格原价:价格*数量float thisPrice = ui->priceEdit->text().toFloat() * ui->numEdit->text().toInt();// 下拉框不同计算策略的索引值int idx = ui->calcSelect->currentIndex();CashContext cc = CashContext(idx);// 传入原价,根据结算规则,得到计算后的实际价格thisPrice = cc.GetResult(thisPrice);// 总计m_fTotalPrice += thisPrice;// 窗口中展示明细ui->showPanel->append("price:" + ui->priceEdit->text()+ ", num:" + ui->numEdit->text()+ ", method:" +  ui->calcSelect->currentText()+ " -> (" + QString::number(thisPrice) + ")");// 显示总计ui->totalShow->setText(QString::number(m_fTotalPrice));
}

版本五的演示结果与版本三、版本四的效果一样,这里不再贴图。

3 总结

本篇介绍了设计模式中的策略模式,并通过商场收费计算软件的实例,使用Qt和C++编程,从基础的收费功能到后续需求的增加,一步步修改代码,来学习策略模式的使用,以及对比策略模式与简单工厂模式的不同。

相关文章:

大话设计模式解读02-策略模式

本篇文章,来解读《大话设计模式》的第2章——策略模式。并通过Qt和C代码实现实例代码的功能。 1 策略模式 策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。 策略模式的特点&#…...

展会邀请 | 龙智即将亮相2024上海国际嵌入式展,带来安全合规、单一可信数据源、可追溯、高效协同的嵌入式开发解决方案

2024年6月12日至14日,备受全球嵌入式系统产业和社群瞩目的2024上海国际嵌入式展(embedded world china 2024)即将盛大开幕,龙智将携行业领先的嵌入式开发解决方案亮相 640展位 。 此次参展,龙智将全面展示专为嵌入式行…...

codeforce round951 div2

A guess the maximum 问题&#xff1a; 翻译一下就是求所有相邻元素中max - 1的最小值 代码&#xff1a; #include <iostream> #include <algorithm>using namespace std;const int N 5e4;int a[N]; int n;void solve() {cin >> n;int ans 0x3f3f3f3f;…...

arcgis开发记录

目录 文章目录 [toc]**arcgis JavaScript API安装**1. arcgisAPI下载地址&#xff1a;https://developers.arcgis.com/downloads/2. 4.4版本API&#xff1a;本地配置3. 3.18版本修改方法 **angular2中加载arcgis JS API**** arcgis加载图层 并显示图层上点的信息****使用图层上…...

RPA-UiBot6.0数据整理机器人—杂乱数据秒变报表

前言 友友们是否常常因为杂乱的数据而烦恼?数据分类、排序、筛选这些繁琐的任务是否占据了友友们的大部分时间?这篇博客将为友友们带来一个新的解决方案,让我们共同学习如何运用RPA数据整理机器人,实现杂乱数据的快速整理,为你的工作减负增效! 在这里,友友们将了…...

Application UI

本节包含关于如何用DevExpress控件模拟许多流行的应用程序ui的教程。 Windows 11 UI Windows 11和最新一代微软Office产品启发的UI。 Office Inspired UI Word、Excel、PowerPoint和Visio等微软Office应用程序启发的UI。 如何&#xff1a;手动构建Office风格的UI 本教程演示…...

关于 Redis 中集群

哨兵机制中总结到&#xff0c;它并不能解决存储容量不够的问题&#xff0c;但是集群能。 广义的集群&#xff1a;只要有多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称之为一个“集群”&#xff0c;例如主从结构中的哨兵模式。 狭义的集群&#xff1a;redis 提供的…...

C++必修:探索C++的内存管理

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. C/C的内存分布 我们首先来看一段代码及其相关问题 int globalVar 1; static…...

python列表---基本语法(浅拷贝,深拷贝等)

文章目录 引言:列表的注意事项1 list中的浅拷贝与深拷贝1.1浅拷贝(Shallow Copy)浅拷贝的方法浅拷贝的效果1.2深拷贝(Deep Copy)深拷贝的方法深拷贝的效果1.3 总结:浅拷贝 vs 深拷贝1.4 为什么浅拷贝顶层元素如果是不可变数据就不能共享,不是传的是引用就相当于传的是地…...

go语言接口之sort.Interface接口

排序操作和字符串格式化一样是很多程序经常使用的操作。尽管一个最短的快排程序只要15 行就可以搞定&#xff0c;但是一个健壮的实现需要更多的代码&#xff0c;并且我们不希望每次我们需要的时候 都重写或者拷贝这些代码。 幸运的是&#xff0c;sort包内置的提供了根据一些排序…...

android:text 总为大写字母的原因

当设置某个 Button 的 text 为英文时&#xff0c;界面上显示的是该英文的大写形式&#xff08;uppercase&#xff09;。例如&#xff1a; <Buttonandroid:id"id/btn"android:layout_width"wrap_content"android:layout_height"wrap_content"…...

CISCN2024 初赛 wp 部分复现(Re)

Misc 1. 火锅链观光打卡 答题即可 Re 1. asm_re 感谢智谱清言&#xff0c;可以读出大致加密算法 这是输入 这是加密部分 这里判断 找到疑似密文的部分&#xff0c;手动改一下端序 #asm_wp def dec(char):return (((char - 0x1E) ^ 0x4D) - 0x14) // 0x50 #return (ord(cha…...

YOLOv10、YOLOv9 和 YOLOv8 在实际视频中的对比

引言 目标检测技术是计算机视觉领域的核心任务之一&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列模型凭借其高效的检测速度和准确率成为了业界的宠儿。本文将详细对比YOLOv10、YOLOv9和YOLOv8在实际视频中的表现&#xff0c;探讨它们在性能、速度和实际应用…...

热题系列章节5

169. 多数元素 给定一个大小为 n 的数组&#xff0c;找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1: 输入: [3,2,3] 输出: 3 示例 2: 输入: [2,2,1,1,1,2,2] 输出:…...

ArcGIS for js 4.x 加载图层

二维&#xff1a; 1、创建vue项目 npm create vitelatest 2、安装ArcGIS JS API依赖包 npm install arcgis/core 3、引入ArcGIS API for JavaScript模块 <script setup> import "arcgis/core/assets/esri/themes/light/main.css"; import Map from arcgis…...

Three.js和Babylon.js,webGL中的对比效果分析!

hello&#xff0c;今天分享一些three.js和babylon.js常识&#xff0c;为大家选择three.js还是babylon.js做个分析&#xff0c;欢迎点赞评论转发。 一、Babylon.js是什么 Babylon.js是一个基于WebGL技术的开源3D游戏引擎和渲染引擎。它提供了一套简单易用的API&#xff0c;使开发…...

flask实现抽奖程序(一)

后端代码E:\LearningProject\lottery\app.py from flask import Flask, render_template import randomapp Flask(__name__)employees [赵一, 钱二, 孙三, 李四, 周五, 吴六, 郑七, 王八]app.route(/) def hello_world():return render_template(index.html, employeesemplo…...

Python中数据库连接的管理

在现代应用程序中&#xff0c;数据库是一个至关重要的组件。无论是小型应用还是大型分布式系统&#xff0c;良好的数据库连接管理都是确保系统高效、可靠运行的关键。本文将详细介绍在Python中管理数据库连接的最佳实践和技术&#xff0c;包括连接池、ORM&#xff08;对象关系映…...

【JAVA技术】mybatis 数据库敏感字段加解密方案

引言&#xff1a;自从有公司项目前2年做了三级等保&#xff0c;每年一度例行公事&#xff0c;昨天继续配合做等保测试。这2天比较忙&#xff0c;这里整理之前写的一篇等保技术文章。 正文&#xff1a; 现在公司项目基本用mybatis实现&#xff0c;但由于项目跨度年份比较久&…...

Collections工具类及其案例

package exercise;public class Demo1 {public static void main(String[] args) {//可变参数//方法形参的个数是可以发生变化的//格式&#xff1a;属性类型...名字//int...argsint sum getSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);System.out.println(sum);}//底层&#xff1a;可…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...