大话设计模式解读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 问题: 翻译一下就是求所有相邻元素中max - 1的最小值 代码: #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下载地址:https://developers.arcgis.com/downloads/2. 4.4版本API:本地配置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。 如何:手动构建Office风格的UI 本教程演示…...
关于 Redis 中集群
哨兵机制中总结到,它并不能解决存储容量不够的问题,但是集群能。 广义的集群:只要有多个机器,构成了分布式系统,都可以称之为一个“集群”,例如主从结构中的哨兵模式。 狭义的集群:redis 提供的…...
C++必修:探索C++的内存管理
✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 贝蒂的主页: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 行就可以搞定,但是一个健壮的实现需要更多的代码,并且我们不希望每次我们需要的时候 都重写或者拷贝这些代码。 幸运的是,sort包内置的提供了根据一些排序…...
android:text 总为大写字母的原因
当设置某个 Button 的 text 为英文时,界面上显示的是该英文的大写形式(uppercase)。例如: <Buttonandroid:id"id/btn"android:layout_width"wrap_content"android:layout_height"wrap_content"…...
CISCN2024 初赛 wp 部分复现(Re)
Misc 1. 火锅链观光打卡 答题即可 Re 1. asm_re 感谢智谱清言,可以读出大致加密算法 这是输入 这是加密部分 这里判断 找到疑似密文的部分,手动改一下端序 #asm_wp def dec(char):return (((char - 0x1E) ^ 0x4D) - 0x14) // 0x50 #return (ord(cha…...
YOLOv10、YOLOv9 和 YOLOv8 在实际视频中的对比
引言 目标检测技术是计算机视觉领域的核心任务之一,YOLO(You Only Look Once)系列模型凭借其高效的检测速度和准确率成为了业界的宠儿。本文将详细对比YOLOv10、YOLOv9和YOLOv8在实际视频中的表现,探讨它们在性能、速度和实际应用…...
热题系列章节5
169. 多数元素 给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [3,2,3] 输出: 3 示例 2: 输入: [2,2,1,1,1,2,2] 输出:…...
ArcGIS for js 4.x 加载图层
二维: 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,今天分享一些three.js和babylon.js常识,为大家选择three.js还是babylon.js做个分析,欢迎点赞评论转发。 一、Babylon.js是什么 Babylon.js是一个基于WebGL技术的开源3D游戏引擎和渲染引擎。它提供了一套简单易用的API,使开发…...
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中数据库连接的管理
在现代应用程序中,数据库是一个至关重要的组件。无论是小型应用还是大型分布式系统,良好的数据库连接管理都是确保系统高效、可靠运行的关键。本文将详细介绍在Python中管理数据库连接的最佳实践和技术,包括连接池、ORM(对象关系映…...
【JAVA技术】mybatis 数据库敏感字段加解密方案
引言:自从有公司项目前2年做了三级等保,每年一度例行公事,昨天继续配合做等保测试。这2天比较忙,这里整理之前写的一篇等保技术文章。 正文: 现在公司项目基本用mybatis实现,但由于项目跨度年份比较久&…...
Collections工具类及其案例
package exercise;public class Demo1 {public static void main(String[] args) {//可变参数//方法形参的个数是可以发生变化的//格式:属性类型...名字//int...argsint sum getSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);System.out.println(sum);}//底层:可…...
Duck Bro的第512天创作纪念日
Tips:发布的文章将会展示至 里程碑专区 ,也可以在 专区 内查看其他创作者的纪念日文章 我的创作纪念日第512天 文章目录 我的创作纪念日第512天一、与CSDN平台的相遇1. 为什么在CSDN这个平台进行创作?2. 创作这些文章是为了赚钱吗?…...
【机器学习】GPT-4中的机器学习如何塑造人类与AI的新对话
🚀时空传送门 🔍引言📕GPT-4概述🌹机器学习在GPT-4中的应用🚆文本生成与摘要🎈文献综述与知识图谱构建🚲情感分析与文本分类🚀搜索引擎优化💴智能客服与虚拟助手…...
晨控CK-UR12-E01与欧姆龙NX/NJ系列EtherNet/IP通讯手册
晨控CK-UR12-E01与欧姆龙NX/NJ系列EtherNet/IP通讯手册 晨控CK-UR12-E01 是天线一体式超高频读写器头,工作频率默认为902MHz~928MHz,符合EPC Global Class l Gen 2/IS0-18000-6C 标准,最大输出功率 33dBm。读卡器同时…...
模板显式、隐式实例化和(偏)特化、具体化的详细分析
最近看了<The C Programing Language>看到了模板的特化,突然想起来<C Primer>上说的显式具体化、隐式具体化、特化、偏特化、具体化等概念弄得头晕脑胀,我在网上了找了好多帖子,才把概念给理清楚。 看着这么多叫法,其…...
软件设计师笔记-计算机系统基础知识
CPU的功能 CPU(中央处理器)是计算机的核心部件,负责执行计算机的指令和处理数据。它的功能主要可以分为程序控制、操作控制、时间控制和数据处理四个方面: 程序控制:CPU的首要任务是执行存储在内存中的程序。程序控制功能确保CPU能够按照程序的指令序列,一条一条地执行。…...
flink 作业动态维护更新,不重启flink,不提交作业
Flink任务实时获取并更新规则_flink任务流实时变更-CSDN博客 一种动态更新flink任务配置的方法_flink 数据源 动态更新-CSDN博客 Flink CEP在实时风控场景的落地与优化 最佳实践 - 在SQL任务中使用Flink CEP - 《实时计算用户手册-v4.5.0》 Flink SQL CEP详解-CSDN博客 如…...
为何数据仓库需要“分层次”?
在数据驱动的商业世界中,数据仓库是企业决策的心脏。然而,一个高效、可扩展且易于管理的数据仓库,需要精心设计和构建。分层是构建数据仓库的关键策略之一。本文将探讨数据仓库分层的重要性以及它如何帮助企业更好地管理数据。 数据仓库分层…...
小熊家务帮day15-day18 预约下单模块(预约下单,熔断降级,支付功能,退款功能)
目录 1 预约下单1.1 需求分析1.1.1 业务流程1.1.2 订单状态 1.2 系统设计1.2.1 订单表设计1.2.2 表结构的设置 1.3 开发远程调用接口1.3.0 复习下远程调用的开发1.3.1 查询地址簿远程接口jzo2o-api工程定义接口Customer服务实现接口 1.3.2 查询服务&服务项远程接口jzo2o-ap…...
[word] word悬挂缩进怎么设置? #经验分享#职场发展#经验分享
word悬挂缩进怎么设置? 在编辑Word的时候上方会有个Word标尺,相信很多伙伴都没使用过。其实它隐藏着很多好用的功能,今天就给大家分享下利用这个word标尺的悬挂缩进怎么设置,一起来看看吧! 1、悬挂缩进 选中全文&…...
6-Maven的使用
6-Maven的使用 常用maven命令 //常用maven命令 mvn -v //查看版本 mvn archetype:create //创建 Maven 项目 mvn compile //编译源代码 mvn test-compile //编译测试代码 mvn test //运行应用程序中的单元测试 mvn site //生成项目相关信息的网站 mvn package //依据项目生成 …...
7k7k传奇世界网页版/惠州seo怎么做
新人刚来,带给大家一些福利,希望大家多关注我的博客,我会不定期的发放一些资料免费给大家!http://yunpan.cn/cjHYq4bUuJqub 访问密码 1d6b c语言视频http://yunpan.cn/cjHYWnaGtFKK2 访问密码 0afb armlinux 书籍和视频h…...
北京网站建公司新闻/站外推广方式
考虑到有时需要由速度时程计算加速度时程,或者由位移时程计算速度时程,采用Matlab编写了由速度时程计算加速度时程函数,采用了五点中心差分方法。函数说明如下:%% Main information% Developed by Decaihfut 2014/11/15% Calcula…...
网站备案是需要去哪里做/2022最新热点事件及点评
说明:LoadBalanced采用轮训的方式请求服务提供者,但是如果针对某些业务需要精确到某个服务提供者或者遍历所有的服务提供者,那么可以通过LoadBalancerClient去获得。 参考: http://blog.csdn.net/message_lx/article/details/5667…...
aws如何搭建wordpress/百度推广管理
1. Telnet Telnet:(Telecommunication和Network的联合缩写) 是TCP/IP协议族中的一员,属于应用层协议,是Internet远程登录服务器的标准协议和主要方式。 telnet服务属于典型的客户机/服务器模型,当用telnet…...
信科网络广州建网站/东莞网站seo公司
原文链接:【ACL2020】DeeBERT:衡量性能与效率的 BERT 推理方法 DeeBERT 作者信息 Elesdspline 目前从事NLP与知识图谱相关工作。 导语 近年来预训练在 NLP 领域的各个任务上都表现出来很好的效果,但是在推理速度方面却不如人意,…...
深圳网站设计知名乐云seo/抖音搜索优化
Spring 容器核心可归纳为两个类: BeanFactory 和 ApplicationContext,ApplicationContext 继承自 BeanFactory ,其不仅包含 BeanFactory 所有功能,还扩展了容器功能。ApplicationContext 核心其实是 refresh 方法,容器…...