重修设计模式-行为型-状态模式
重修设计模式-行为型-状态模式
先了解一下状态机的概念,状态机是软件编程中对一种状态场景的抽象表达,构成状态机三要素是:状态(State)、事件(Event)、动作(Action),事件也称为转移条件,事件驱动状态的转移,并触发对应的动作,其中动作的触发不是必须的。
状态机是一种抽象概念,而状态模式是状态机的一种编码实现方式,其实还有分支判断法和图表法可以实现状态机。
以电商中订单系统为例,订单有待付款,待发货,待收货,已完成和已取消状态,而且每个状态还要有特定的事件才能驱动状态的转移和动作触发,比如待付款状态的订单,由付款和取消事件驱动订单到待发货和已取消状态,不响应发货事件;待发货状态订单只由发货和取消事件驱动到下一状态,而且取消后还要触发退款的动作,用一个图来表示这个关系:

订单是一种非常典型的状态机场景,这种场景的状态、事件和动作都是可以预见的,编码时可以先表达出状态机的三要素:
//订单状态:
enum class OrderState(val value: Int, val desc: String) {WAIT_PAYMENT(0, "待付款"),WAIT_SHIPMENT(1, "待发货"),WAIT_RECEIPT(2, "待收货"),COMPLETED(3, "已完成"),CANCELLED(4, "已取消")
}//触发动作:
object ActionGroup {fun moneyToPlatform() {println("行为:付款给平台...")}fun moneyToSeller() {println("行为:金额打给商家...")}fun moneyToBuyer() {println("行为:金额退还给买家...")}
}//状态机:
class OrderStateMachine {private var currentState: OrderState = OrderState.WAIT_PAYMENT//事件:买家付款fun payment() {}//事件:商家发货fun shipment() {}//事件:买家收货fun receipt() {}//事件:买家/商家取消fun cancelled() {}
}
下面是测试代码,共测试了三个流程,其中流程一、二状态是正常的状态流转,流程三在取消状态后再调用发货事件,用于检查程序是否响应这一错误事件。
fun main() {println("流程一:")val stateMachine1 = OrderStateMachine()stateMachine1.payment()stateMachine1.shipment()stateMachine1.receipt()println("")println("流程二:")val stateMachine2 = OrderStateMachine()stateMachine2.cancelled()println("")println("流程三:")val stateMachine3 = OrderStateMachine()stateMachine3.payment()stateMachine3.cancelled()stateMachine3.shipment()println("")
}
准备工作都做好了,下面开始用三种方法进行状态机的实现。
1.状态机实现—分支判断法:
这种方式会将需求简单的直译成代码,集中处理事件逻辑,并在每个事件中考虑所有状态的实现,下面按照这种方式将代码补全:
//状态机:
class OrderStateMachine {private var currentState: OrderState = OrderState.WAIT_PAYMENT //已待付款作为初始状态//事件:买家付款fun payment() {println("事件:买家付款")when (currentState) {OrderState.WAIT_PAYMENT -> {ActionGroup.moneyToPlatform()currentState = OrderState.WAIT_SHIPMENT}OrderState.WAIT_SHIPMENT, OrderState.WAIT_RECEIPT, OrderState.COMPLETED, OrderState.CANCELLED -> {println("待发货、待收货、已完成和已取消的订单不用付款...")}}println("订单状态: ${currentState.desc}")}//事件:商家发货fun shipment() {println("事件:商家发货")when (currentState) {OrderState.WAIT_SHIPMENT -> {currentState = OrderState.WAIT_RECEIPT}OrderState.WAIT_PAYMENT, OrderState.WAIT_RECEIPT, OrderState.COMPLETED, OrderState.CANCELLED -> {println("待付款、待收货、已完成和已取消的订单不用发货...")}}printState()}//事件:买家收货fun receipt() {println("事件:买家收货")when (currentState) {OrderState.WAIT_RECEIPT -> {ActionGroup.moneyToSeller()currentState = OrderState.COMPLETED}OrderState.WAIT_PAYMENT, OrderState.WAIT_SHIPMENT, OrderState.COMPLETED, OrderState.CANCELLED -> {println("待付款,待发货、已完成和已取消的订单不用收货...")}}printState()}//事件:买家/商家取消fun cancelled() {println("事件:买家/商家取消")when (currentState) {OrderState.WAIT_PAYMENT -> {currentState = OrderState.CANCELLED}OrderState.WAIT_SHIPMENT -> {ActionGroup.moneyToBuyer()currentState = OrderState.CANCELLED}OrderState.WAIT_RECEIPT, OrderState.COMPLETED, OrderState.CANCELLED -> {println("待收货、已完成和已取消的订单不能取消...")}}printState()}fun printState() {println("订单状态: ${currentState.desc}")}}
运行一下看结果:
流程一:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:商家发货
订单状态: 待收货
事件:买家收货
动作:金额打给商家...
订单状态: 已完成流程二:
事件:买家/商家取消
订单状态: 已取消流程三:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:买家/商家取消
动作:金额退还给买家...
订单状态: 已取消
事件:商家发货
待付款、待收货、已完成和已取消的订单不用发货...
订单状态: 已取消
可以看到流程一二状态正常流转,流程三已取消订单并不会响应发货事件,代码执行结果是符合预期的。
再看上述代码,包含了大量的 if-else / switch-case 判断( when 是 Kotlin语言表达 switch-case 的语法糖),这些冗长的分支逻辑很容易改错代码引发Bug,可读性很差。如果再增加 待评价 状态和 评价 事件,那么这时代码的改动会涉及到所有事件方法,代码维护性也很差。
这种实现方法只适合简单的状态机,对于复杂的状态机还是用下面两种实现方式。
2.状态机实现—查表法:
我们把事件也抽象成枚举:
//订单事件:
enum class OrderEvent(val value: Int, val desc: String) {PAYMENT(0, "事件:买家付款"),SHIPMENT(1, "事件:商家发货"),RECEIPT(2, "事件:买家收货"),CANCEL(3, "事件:买家/商家取消")
}
再根据上面的状态流转图,定义出状态的流转表:
| 状态\事件 | PAYMENT | SHIPMENT | RECEIPT | CANCEL |
|---|---|---|---|---|
| WAIT_PAYMENT | WAIT_SHIPMENT (动作:moneyToPlatform) | \ | \ | CANCELLED |
| WAIT_SHIPMENT | \ | WAIT_RECEIPT | \ | CANCELLED 动作:moneyToBuyer |
| WAIT_RECEIPT | \ | \ | COMPLETED 动作:moneyToSeller | \ |
| COMPLETED | \ | \ | \ | \ |
| CANCELLED | \ | \ | \ | \ |
这个表也是查表法的核心,只要能在代码中正确的表达这个表,就可以非常简单的实现状态机,这里用了一个取巧的方式,将状态枚举和事件枚举的 value 和所在数组下标进行了对应,代码如下:
//状态机:
class OrderStateMachine2 {//状态-事件流转表private val STATE_EVENT_TABLE = arrayOf(arrayOf<OrderState?>(OrderState.WAIT_SHIPMENT, null, null, OrderState.CANCELLED),arrayOf<OrderState?>(null, OrderState.WAIT_RECEIPT, null, OrderState.CANCELLED),arrayOf<OrderState?>(null, null, OrderState.COMPLETED, null),arrayOf<OrderState?>(null, null, null, null),arrayOf<OrderState?>(null, null, null, null))//状态-动作触发表private val STATE_ACTION_TABLE = arrayOf(arrayOf<Function0<Unit>?>(::moneyToPlatform, null, null, null),arrayOf<Function0<Unit>?>(null, null, null, ::moneyToBuyer),arrayOf<Function0<Unit>?>(null, null, ::moneyToSeller, null),arrayOf<Function0<Unit>?>(null, null, null, null),arrayOf<Function0<Unit>?>(null, null, null, null))private var currentState: OrderState = OrderState.WAIT_PAYMENT //已待付款作为初始状态//事件:买家付款fun payment() {println("事件:买家付款")executeEvent(OrderEvent.PAYMENT)println("订单状态: ${currentState.desc}")}//事件:商家发货fun shipment() {println("事件:商家发货")executeEvent(OrderEvent.SHIPMENT)printState()}//事件:买家收货fun receipt() {println("事件:买家收货")executeEvent(OrderEvent.RECEIPT)printState()}//事件:买家/商家取消fun cancel() {println("事件:买家/商家取消")executeEvent(OrderEvent.CANCEL)printState()}private fun executeEvent(event: OrderEvent) {//触发动作STATE_ACTION_TABLE.getOrNull(currentState.value)?.getOrNull(event.value)?.invoke()val nextState = STATE_EVENT_TABLE.getOrNull(currentState.value)?.getOrNull(event.value)if (nextState != null) {currentState = nextState} else {println("${currentState.desc}不响应${event.desc}")}}fun printState() {println("订单状态: ${currentState.desc}")}
}
执行结果:
流程一:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:商家发货
订单状态: 待收货
事件:买家收货
动作:金额打给商家...
订单状态: 已完成流程二:
事件:买家/商家取消
订单状态: 已取消流程三:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:买家/商家取消
动作:金额退还给买家...
订单状态: 已取消
事件:商家发货
已取消不响应事件:商家发货
订单状态: 已取消
这种方式的核心是维护好两个表,如果新增状态和事件,那么只需要关注表关系是否正确即可,甚至无需对其他代码进行改动,比较适合状态比较多的场景。缺点是对于动作触发不是很灵活,由于每个动作触发的参数传递可能不一样,状态和动作甚至有依赖关系,这种场景下查表法就非常不灵活了。
3.状态机实现—状态模式:
查表法对于复杂动作场景有一定局限性,分支判断法的代码可读性和可维护性比较差,接下来就是主角-状态模式出场了。
状态模式其实就是对分支判断法的进一步封装,通过将事件触发导致的状态转移和动作执行,拆分到不同的状态类中,从而避免大量分支判断逻辑,提高代码可读性和可扩展性,这就是状态模式。
首先定义出事件接口:
//状态流转事件接口,各状态需实现:
interface IOrder {fun getDesc(): String//Kotlin中接口支持默认实现(高版本的Java也支持了)fun payment(stateMachine: OrderStateMachine3): Unit {println("${stateMachine.getOrderState().getDesc()}不响应事件:买家付款")}fun shipment(stateMachine: OrderStateMachine3): Unit {println("${stateMachine.getOrderState().getDesc()}不响应事件:商家发货")}fun receipt(stateMachine: OrderStateMachine3): Unit {println("${stateMachine.getOrderState().getDesc()}不响应事件:买家收货")}fun cancel(stateMachine: OrderStateMachine3): Unit {println("${stateMachine.getOrderState().getDesc()}不响应事件:买家/商家取消")}
}
定义所有状态类,并实现总的事件接口,然后根据具体状态选择实现抽象的事件方法,并在方法中实现状态流转和动作的触发逻辑。比如待付款状态订单只关心付款事件和取消事件,那么只实现这两个方法即可:
//object是Kotlin的单例写法,JVM 加载类时就创建了单例对象
//状态:待付款
object OrderWaitPayment : IOrder {override fun getDesc(): String = "待付款"override fun payment(stateMachine: OrderStateMachine3) {stateMachine.setOrderState(OrderWaitShipment)println("动作:付款给平台...")}override fun cancel(stateMachine: OrderStateMachine3) {stateMachine.setOrderState(OrderCanceled)}
}//状态:待发货
object OrderWaitShipment : IOrder {override fun getDesc(): String = "待发货"override fun shipment(stateMachine: OrderStateMachine3) {stateMachine.setOrderState(OrderWaitReceipt)}override fun cancel(stateMachine: OrderStateMachine3) {stateMachine.setOrderState(OrderCanceled)println("动作:金额退还给买家...")}}//状态:待收货
object OrderWaitReceipt : IOrder {override fun getDesc(): String = "待收货"override fun receipt(stateMachine: OrderStateMachine3) {stateMachine.setOrderState(OrderCompleted)println("动作:金额打给商家...")}
}//状态:已完成
object OrderCompleted: IOrder {override fun getDesc(): String = "已完成"
}//状态:已取消
object OrderCanceled: IOrder {override fun getDesc(): String = "已取消"
}
状态机代码:
//状态机:
class OrderStateMachine3 {private var currentState: IOrder = OrderWaitPayment //待付款作为初始状态fun setOrderState(orderState: IOrder) {currentState = orderState}fun getOrderState(): IOrder = currentState//事件:买家付款fun payment() {println("事件:买家付款")currentState.payment(this)printState()}//事件:商家发货fun shipment() {println("事件:商家发货")currentState.shipment(this)printState()}//事件:买家收货fun receipt() {println("事件:买家收货")currentState.receipt(this)printState()}//事件:买家/商家取消fun cancel() {println("事件:买家/商家取消")currentState.cancel(this)printState()}private fun printState() {println("订单状态: ${currentState.getDesc()}")}
}
执行结果:
流程一:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:商家发货
订单状态: 待收货
事件:买家收货
动作:金额打给商家...
订单状态: 已完成流程二:
事件:买家/商家取消
订单状态: 已取消流程三:
事件:买家付款
动作:付款给平台...
订单状态: 待发货
事件:买家/商家取消
动作:金额退还给买家...
订单状态: 已取消
事件:商家发货
已取消不响应事件:商家发货
订单状态: 已取消
代码输出符合预期,如果增加新的状态和事件,那么只需要新增个状态类和方法即可,扩展非常方便,可读性也很高。
缺点是如果状态非常多,也需要定义出大量的状态类,如果状态类的实现又只涉及状态流转而少有事件执行,那么类的模板代码甚至超过具体逻辑代码,就得不偿失了,这种情况图表法更适用。
总结
状态机三要素:状态(State)、事件(Event)、动作(Action),事件驱动状态的流转,并触发动作的执行。
实现状态及三种方式:
-
分支判断法:
优点:实现简单,适合状态较少的简单场景。
缺点:大量 if-else 或 switch-case 代码,可读性和可扩展性差,不适合复杂逻辑。
-
查表法:
优点:代码中只需维护好状态流转表即可,代码比较直观,适合状态较多,且增加频繁的场景。
缺点:不适合动作执行复杂的场景,如订单系统
-
状态模式:
优点:分支判断法的进一步封装,加强了代码可读性和扩展性,适合状态数量适中,动作执行复杂的场景。
缺点:大量状态会导致状态类繁多,体积变大。
如何选择状态机的实现方法还需要根据具体场景,考虑当前需求实现健壮性,保持一定前瞻性,编码初期避免过度封装,适时重构,保持良好编码习惯。
相关文章:
重修设计模式-行为型-状态模式
重修设计模式-行为型-状态模式 先了解一下状态机的概念,状态机是软件编程中对一种状态场景的抽象表达,构成状态机三要素是:状态(State)、事件(Event)、动作(Action)&…...
网络安全知识渗透测试
渗透测试是一种模拟网络攻击,用于识别漏洞并制定规避防御措施的策略。及早发现缺陷使安全团队能够修复任何漏洞,从而防止数据泄露,否则可能会造成数十亿美元的损失。笔测试还有助于评估组织的合规性、提高员工对安全协议的认识、评估事件响应…...
我国卫星互联网产业集群崛起;1000万资金扶持 上海助推产业互联网平台跨越式发展;河南“数据要素×”行动实施方案发布 | 产业互联网观察第179期
我国卫星互联网产业集群崛起:千帆星座首批卫星发射成功 8月6日,中国版"星链"项目"千帆星座"(G60星链)首批18颗组网卫星在太原卫星发射中心成功发射升空。这些卫星采用上海格思航天自主研发的可堆叠型平板卫星…...
《RT-DETR》论文笔记
原文出处 [2304.08069] DETRs Beat YOLOs on Real-time Object Detection (arxiv.org)https://arxiv.org/abs/2304.08069 原文笔记 What DETRs Beat YOLOs on Real-time Object Detection 1、设计了一种高效的混合编码器,通过解耦尺度内交互和跨尺度融合来提高…...
输出Docker容器的启动命令行脚本
当Docker容器启动后,如果忘记启动参数,比如目录挂载、端口映射等,可以通过Portainer等容器管理工具查看。但是,有时希望能获取容器启动的命令行,因为需要再启动一个类似容器,怎么办呢? 有一款工…...
Dubbo 快速掌握 这篇就够了
1. Dubbo概述 Dubbo 是一款高性能、轻量级的开源Java RPC框架,由阿里巴巴公司开发并在2011年开源。它主要用于解决分布式系统中服务之间的通信问题,支持多种协议,如Dubbo、HTTP、Hessian等,具有服务注册、服务发现、负载均衡、故…...
【每日刷题】Day100
【每日刷题】Day100 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 【模板】堆_牛客题霸_牛客网 (nowcoder.com) 2. 【模板】链表_牛客题霸_牛客网 (nowcoder.com) 3…...
网络协议九 应用层 HTTPS
一 什么是 HTTPS 二 什么是 SSL/TLS 协议 ,TLS 是 SSL 升级后的名字 三. TLS 协议 工作在那一层 四 。OpenSSL 是 SSL/TLS协议的开源实现。 五。重点 HTTPS 的通讯过程 六 TLS 1.2 的连接过程 1. client hello 是浏览器发送给服务器的第一条信息, 是客户…...
【ArrayList】JDK1.8源码详细注释 以及如何实现线程安全的链表
ArrayList(JDK8) ArrayList有四个内部类,成员内部类Itr,成员内部类ListItr,静态内部类SubList,ArrayListSpliterator(暂时用不到)Itr是Iterator的实现类,支持正向遍历,ArrayList的i…...
[python]rasterio运行代码警告proj_create_from_database: Cannot find proj.db
这个报错要分原因还有rasterio版本讨论,因此官方给出了十分具体回答 Frequently Asked Questions What does "RasterioIOError: file.ecw not recognized as a supported file format." mean? This exception is raised when none of rasterios format …...
ThinkPHP5.1.C+CmsEasy-SQL注入
目录 1、ThinkPHP 中存在的 SQL注入 漏洞( select 方法注入) 1.1环境配置 1.1.1将 composer.json 文件的 require 字段设置成如下: 1.1.2设置application/index/controller/Index.php 文件 1.1.3在 application/database.php 文件中配置…...
Python 绘图进阶之词云图:文本数据的可视化艺术
Python 绘图进阶之词云图:文本数据的可视化艺术 引言 在数据科学和自然语言处理领域,词云图(Word Cloud)是一种常用的可视化工具。它通过直观的图形展示文本数据中的高频词汇,使得我们能够快速抓住文本内容的核心主题…...
【Windows】Q-Dir(资源管理器)软件介绍
软件介绍 Q-Dir是一款免费的文件管理器软件,它可以让您更方便地浏览和管理计算机上的文件和文件夹。与Windows自带的资源管理器相比,Q-Dir具有更多的功能和选项。 安装教程 软件下载完成,解压软件。 点击Q-Dir.exe即可打开软件。 功能…...
什么是令牌桶算法?工作原理是什么?使用它有哪些优点和注意事项?
大家好,我是鸭鸭! 此答案节选自鸭鸭最近弄的面试刷题神器面试鸭 ,更多大厂常问面试题,可以点击下面的小程序进行阅读哈! 目前这个面试刷题小程序刚出,有网页和小程序双端可以使用! 回归面试题…...
C++-类与对象(中上篇)
一、目标 1. 类的 6 个默认成员函数 2. 构造函数 3. 析构函数 二、对目标的介绍 1. 类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生…...
链表 206.反转链表
一般方法 不需要一个个来回换,只需要改变链表的指向,即可完成 一个链表的头节点,也代表了整个链表 class Solution {public ListNode reverseList(ListNode head) {ListNode temp;ListNode cur head;ListNode pre null;while(cur ! null…...
Ubuntu18.04 配置EtherCAT主站IGH SOEM
IGH IGH 是开源的EtherCAT 主站软件 一、安装依赖 sudo apt update sudo apt install build-essential linux-headers-$(uname -r) mercurial autoconf libtool 也不知道安装的完全不完全 uname -r 可以查看内核,我安装的ubuntu18.04的内核版本是 5.4.0-84-gen…...
航空航天构型管理
构型管理(CM)被定义为在产品的生命周期中应用的SE技术和管理规程。CM的五个原则是:CM计划与执行、配置识别、配置变更和差异控制、配置状态核算和配置验证。 广义上的构型管理规划和管理是有效实施配置管理的关键。特别是在不同项目之间的差异中,构型管理…...
Visual Studio Code 安装与 C/C++ 语言运行总结
大家好,我是程序员小羊! 前言: Visual Studio Code(简称 VS Code)是由微软开发的一款轻量级、强大的代码编辑器,支持多种编程语言和开发框架。由于其丰富的插件生态系统和灵活的配置选项,VS…...
Science Robotics 受鳞片启发的可编程机器人结构,可同时进行形状变形和刚度变化
一、前言速览 生物有机体通常凭借复杂的结构表现出显著的多功能性,例如章鱼具有可以同时改变形状和刚度的能力。现有的仿生软体机器人要想实现这样的能力,往往需要繁琐的结构和复杂的控制系统。为此,来自新加坡南洋理工大学的研究人员从覆盖…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
