设计心得——解耦的实现技术
一、说明
在前面的“设计心得——解耦”中,对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明,以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践,就需要不断的进行总结分析,有一个否定之否定的过程。
二、解耦的技术
实现解耦的技术和手段非常多,常见的有以下几种:
1、抽象接口
通过接口来实现类间的解耦是非常常见的手段,在C++中一般是使用抽象类中的纯虚函数来进行接口抽象。通过具体的实现类来完成抽象接口中的统一接口,从而达到解耦的目的。类似下面的这种:
#include <iostream>
#include <memory>// 抽象接口类 Shape
class Shape {
public:virtual void draw() const = 0;virtual ~Shape() = default;
};// 子类Circle
class Circle : public Shape {
public:void draw() const override {std::cout << "Drawing a Circle" << std::endl;}
};// 子类 Rectangle
class Rectangle : public Shape {
public:void draw() const override {std::cout << "Drawing a Rectangle" << std::endl;}
};void drawShape(const std::shared_ptr<Shape>& shape) {shape->draw();
}int main() {auto circle = std::make_shared<Circle>();auto rectangle = std::make_shared<Rectangle>();drawShape(circle);drawShape(rectangle);return 0;
}
例程简单明了,一眼就能看出来接口的意思。另外模块间的API接口其实也可以划到这部分:
int open(const char *pathname, int flags, mode_t mode);
Linux系统的文件打开API函数。
2、设计模式
在设计模式中提供了一些解耦的手段,如工厂模式、策略模式和命令模式等等
#include <iostream>
#include <memory>
//接口抽象
class MoveStrategy {
public:virtual ~MoveStrategy() = default;virtual void move() const = 0;
};
//具体策略
class WalkStrategy : public MoveStrategy {
public:void move() const override {std::cout << "The Role is walking." << std::endl;}
};class RunStrategy : public MoveStrategy {
public:void move() const override {std::cout << "The Role is running." << std::endl;}
};class JumpStrategy : public MoveStrategy {
public:void move() const override {std::cout << "The Role is jumping." << std::endl;}
};
//角色类
class Role {
private:std::shared_ptr<MoveStrategy> moveStrategy;public:Role(std::shared_ptr<MoveStrategy> strategy): moveStrategy(std::move(strategy)) {}void setMoveStrategy(std::shared_ptr<MoveStrategy> strategy) {moveStrategy = std::move(strategy);}void move() const {moveStrategy->move();}
};
int main() {// 创建角色,并设置其移动策略auto role = std::make_shared<Role>(std::make_shared<WalkStrategy>());role->move();//使用跑动策略role->setMoveStrategy(std::make_shared<RunStrategy>());role->move();//使用跳跃策略role->setMoveStrategy(std::make_shared<JumpStrategy>());role->move();return 0;
}
其它设计模式基本的方法类似。
3、控制反转(依赖注入)
这个例子非常多,前面也刚刚分析过就不再举例了。
4、泛型编程(模板编程 )
模板编程的优势在于适应性更强,编码灵活,便于优化,但使用不当可能会引起代码膨胀等问题。但最主要的是引入的复杂性,要根据情况取舍,看一个简单的比较处理:
#include <iostream>
#include <type_traits>template <typename T>
decltype(auto) compare(const T& a, const T& b) {return a < b;
}struct MyType {int value;MyType(int v) : value(v) {}bool operator<(const MyType& other) const {return value < other.value;}
};int main() {int x = 5, y = 10;double a = 3.14, b = 2.71;MyType m1(1), m2(2);compare(x,y);compare(a,b);compare(m1,m2);return 0;
}
5、服务隔离
也就常提到的面向服务编程,包括消息队列服务、流服务和远程服务
//services
class PostProcess(http_request request){
virtual std::string recvRequest(http_request request) = 0;
};
class PostPlatform(http_request request):public PostProcess{
virtual std::string recvRequest(http_request request){std::cout<<"Platform recv request!"<<std::endl;return "platform";
}
};
class PostMerchant(http_request request):public PostProcess{
virtual std::string recvRequest(http_request request){std::cout<<"Merchant recv request!"<<std::endl;return "merchant";
}
};
//client
std::string sendRequest(PostProcess *p,http_request request){auto s = p->recvRequest(request)return s;
}
int main() {PostPlatform pp;http_request request("exchange goods");sendRequest(&pp,request);return 0;
}
6、其它
这一其它就多了,不过除了上面那几个技术,象COM技术、插件技术等等都是用得虽然不多,但名气可不小的。此处就不再举例 ,有兴趣的可以看看一些开源框架或源码,如MySql的源码中就使用了插件技术。
三、比较和应用
在上面的几种解耦技术中,对大多数C++程序员来说,经常使用的还是在前四个居多。但无论哪种应用,一个前提就是不能太复杂,所以泛型编程可能对很多小伙伴来说就又被剔除了。而控制反转和设计模式一般来说都和一定场景有关,所以最后留下来的,就是一个,抽象接口来实现解耦。
或者回过头来说,抽象接口是后面所有的解耦手段的基础,掌握了接口抽象的能力,就具备在设计层次向更高一层前进的能力。
四、总结
设计是一个不断沉淀的过程,没有人可能一下就掌握了设计的全部精髓。这就和一个人的成长一样,从婴儿到成为一个健硕的青年,中间可能会经过无数的大大小小的错误,既有身体疾病上的成长的过程,也有思想不断成熟的过程。
所以,设计只是一个人思想的外延。它既受主观的影响也爱外面客观的实践的影响。
相关文章:
设计心得——解耦的实现技术
一、说明 在前面的“设计心得——解耦”中,对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明,以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践,就需要不断的…...
k2路由器登录校园网
教程1刷入Breed,并手动刷入Padavan固件:斐讯K1、K2、K2P 刷机、刷入Breed 辅助工具 | tb (tbvv.net) Padavan下载网址: 我用的是: Padavan 登录的网址是 192.168.123.1 Padavan配置教程: 先用网线连上校园网&#…...
基于Springboot学生宿舍水电信息管理系统【附源码】
基于Springboot学生宿舍水电信息管理系统 效果如下: 系统登陆页面 系统用户首页 用电信息页面 公告信息页面 管理员主页面 用水信息管理页面 公告信息页面 用户用电统计页面 研究背景 随着高校后勤管理信息化的不断推进,学生宿舍水电管理作为高校后勤…...
手机怎样玩电脑游戏?
如果您正在寻找一款能够实现手机远程控制电脑玩游戏的软件,本文推荐远程看看软件。这款软件不仅支持手机远程控制电脑,还具备电脑与电脑之间的多端互控功能,您能够随时随地畅玩游戏,享受无缝的游戏体验。此外,远程看看…...
【Linux网络】认识协议(TCP/UDP)、Mac/IP地址和端口号、网络字节序、socket套接字
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、初识协议2、UDP、TCP3、Mac、IP地址4、端口号5、网络字节序6、socket 1、初识协议 协议就是一种约定。如何让不同厂商生产的计…...
【软考知识】奇偶校验码,循环冗余码,海明码介绍
文章目录 **1. 奇偶校验码 (Parity Check Code)****基本原理****算法流程****优点与缺点****应用场景** **2. 循环冗余码 (Cyclic Redundancy Check, CRC)****基本原理****算法流程****例子****优点与缺点****应用场景** **3. 海明码 (Hamming Code)****基本原理****算法流程**…...
SOME/IP--协议英文原文讲解10
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 4.2.2 Req…...
前端面试-网络协议篇
1.http网络协议中post和get有什么区别 在HTTP网络协议中,POST和GET主要有以下区别: 参数传递方式: GET:参数附加在URL后面,如example.com?key1value1&key2value2 。POST:参数放在HTTP请求体中。 数据…...
音视频入门基础:RTP专题(10)——FFmpeg源码中,解析RTP header的实现
一、引言 由《音视频入门基础:RTP专题(9)——FFmpeg接收RTP流的原理和内部实现》可以知道,FFmpeg接收RTP流时,其源码内部会调用rtp_read函数。而rtp_read函数内部会通过recvfrom函数接收基于UDP的RTP音视频数据。一般…...
1.1 go环境搭建及基本使用
golang下载地址: Download and install - The Go Programming Language (google.cn) 验证安装是否成功: go version 查看go环境 go env 注意:Go1.11版本之后无需手动配置环境变量,使用go mod 管理项目,也不需要把项目放到GO…...
Flask flash() 消息示例
目录 安装 Flask 入门:Flask flash() 基本示例 进阶:使用 Flask-WTF Flash 登录结果消息 详解:get_flashed_messages() 详解:flash() 消息的完整生命周期 Flask 提供 flash() 用于向 用户传递临时消息,通常用于: • 表单提交成功或失败 • 用户登录、注册、退出提…...
Gemini 2.0助力科学突破,AI联合科学家系统登场
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
京东外卖骑手全部缴纳五险一金
刘强东这步棋,直击700万骑手软肋? 今天,京东突然甩出一张底牌:自2025年3月1日起,外卖全职骑手全员缴纳五险一金,兼职骑手配套意外医疗双保险。 消息一出,直接炸了外卖江湖。要知道,…...
oracle apex post接口
日常记录 使用到了apex_json方式接收 、、、1 首先,接口通过body传递过来,成功接收到, 数据格式为 JSON_OBJECT_T l_json : JSON_OBJECT_T.parse(:body); 这里我用参数接收到 然后 里面是包含了 "data" 我用 继续接收到这个 l…...
百度云DeepSeek一体机:百舸、千帆和一见介绍及区别对比
百度智能云DeepSeek一体机百舸、千帆和一见,搭载昆仑芯等国产自研算力芯片,可支持在单机环境下一键部署DeepSeek R1/V3全系列模型。百度云服务器网bdyfwq.com分享百度智能云官方发布的百舸DeepSeek一体机、千帆DeepSeek一体机和一见DeepSeek一体机配置介…...
k8s集群内的pod连接集群外部的mysql, k8s集群内部服务如何连接集群外部mysql? 一文搞明白
一、为什么不将mysql服务部署到k8s集群中使用呢? 1.有状态服务在K8s中的管理比较复杂,特别是持久化存储的问题。虽然K8s有StatefulSet和PV/PVC,但配置和维护起来需要更多工作,同时以下问题仍需解决:-存储可靠性:如果使…...
C#使用Semantic Kernel:接入本地deepseek-r1
安装Ollama 1.下载Ollama 访问Ollama官网(https://ollama.com),选择适合你操作系统的版本进行下载。 对于Linux用户,可以通过以下命令安装: curl -fsSL https://ollama.com/install.sh | sudo bash sudo system…...
【算法】直接插入排序、折半插入排序、希尔排序
1 直接插入排序 时间复杂度:O(N^2) 空间复杂度:O(1) 稳定性:稳定 元素集合越接近有序,直接插入排序算法的时间效率越高 1.1直接插入排序思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中ÿ…...
使用API有效率地管理Dynadot域名,为域名部署DNS安全拓展(DNSSEC)
关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…...
【排版教程】如何在Word/WPS中优雅的插入参考文献
材料展示 随便选取一段综述内容,以及对应的参考文献,如下图所示: 1 参考文献编辑 首先对参考文献部分进行编辑,将其设置自动编号 在段落中,选择悬挂缩进 在编号中,设置自定义编号,然后按照…...
神经形态视觉的实时动态避障系统:突破传统SLAM的响应延迟瓶颈
引言:机器人感知的实时性挑战 斯坦福机器人实验室采用异步脉冲神经网络处理DVS事件相机数据后,动态障碍物响应延迟从34ms降至0.9ms。在20m复杂场景避障测试中,基于神经形态芯片的路径规划系统将SLAM更新频率提升至10kHz,较传统GP…...
python绘图之密集散点图
密集散点图主要目的是生成一个可视化图表,展示 insurance 数据集中 bmi(身体质量指数)和 charges(医疗费用)之间的关系,并通过不同的维度对数据进行分组和区分,以便更清晰地观察数据的分布和特征…...
Linux操作系统4-进程间通信5(共享内存实现两个进程通信)
上篇文章:Linux操作系统4-进程间通信4(共享内存原理,创建,查看,命令)-CSDN博客 本篇Gitee仓库:myLerningCode/l24 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重…...
sam2 windows 编译安装
目录 1. pip install sam2 2. 编译安装 1. pip install sam2 运行报错: cannot import name _C from sam2 (E:\project\smpl\render_blender\linux\GroundedSAM2_SMPL\sam2\__init__.py) 2. 编译安装 cd E:\project\sam2\sam2-main set DISTUTILS_USE_SDK1 py…...
RFID测温技术:电力设备安全监测的新利器
在当今高度依赖电力的现代化社会中,稳定且可靠的电力供应是社会运转的基石。电力设备作为电力系统的关键核心,其运行状态直接关乎电力供应的品质。然而,电力设备长期运行过程中,受到诸如过载、接触不良以及环境因素等多重影响&…...
(一)趣学设计模式 之 单例模式!
目录 一、啥是单例模式?二、为什么要用单例模式?三、单例模式怎么实现?1. 饿汉式:先下手为强! 😈2. 懒汉式:用的时候再创建! 😴3. 枚举:最简单最安全的单例&a…...
自动化办公|xlwings生成图表
在日常的数据分析和报告生成中,Excel图表是一个非常重要的工具。它能够帮助我们直观地展示数据,发现数据中的规律和趋势。然而,手动创建和调整图表往往耗时且容易出错。幸运的是,借助Python的xlwings库,我们可以自动化…...
Docker基于Ollama本地部署大语言模型
一、Ollama介绍 Ollama 是一个开源的大型语言模型(LLM)平台,旨在简化大型语言模型在本地环境中的运行、管理和交互。通过Ollama,用户可以轻松加载和使用各种预训练的语言模型,执行诸如文本生成、翻译、代码编写、问答…...
Pytorch实现之GIEGAN(生成器信息增强GAN)训练自己的数据集
简介 简介:在训练数据样本之前首先利用VAE来推断潜在空间中不同类的分布,用于后续的训练,并使用它来初始化GAN。与ACGAN和BAGAN不同的是,提出的GIEGAN有一个分类器结构,这个分类器主要判断生成的图像或者样本图像属于哪个类,而鉴别器仅判断图像是来自于生成器还是真实样…...
centos9安装k8s集群
以下是基于CentOS Stream 9的Kubernetes 1.28.2完整安装流程(containerd版): 一、系统初始化(所有节点执行) # 关闭防火墙 systemctl disable --now firewalld# 关闭SELinux sed -i "s/SELINUXenforcing/SELINU…...
