架构设计原则:选择 SPI 还是 API ?

从零构建ESP32-S3 SPI驱动框架:深入API设计与多设备并发实践 本文深入探讨如何从零构建ESP32-S3 SPI驱动框架,重点解析其API设计与多设备并发访问策略。通过分析SPI控制器架构、多设备配置、DMA内存管理及中断处理机制,为开发者提供构建稳定高效嵌入式外设系统的实用指南,特别适合工业控制和数据采集等复杂应用场景。 阅读详情

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

203ad1c5b92fed75138f82706906d636.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:www.cnblogs.com/happy
framework/p/3325560.html


背景

第一次听说 SPI 是阅读《软件框架设计的艺术》,以后陆续在 JDBC 和 SpringBoot 中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一个思考过程。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

从面向接口编程说起

c25e06e26206564a728127bdfa3ee8c2.jpeg

我们在“调用方”和“实现方”之间引入了“接口”,上图没有给出“接口”应该位于哪个“包”中,从纯粹的可能性上考虑,我们有三种选择:

  1. “接口”位于“调用方”所在的“包”中。

  2. “接口”位于“实现方”所在的“包”中。

  3. “接口”位于独立的“包”中。

下面让我们依次分析这三种可能性,如果现实中确实有这种可能性,不如我们就为其起个名字以方便交流。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

“接口”位于“调用方”所在的“包”中

我们先想象一个场景,以仓储的接口为例:

f32e7c3ad26edeb27e7529741b979f17.png

我们将“仓储接口”放置于“领域层”这个“包”中,实现放在一个独立的“包”中,我们看DDD大师的实现都是这样子,现在来思考一下为什么这么做。

“领域层”的“领域服务”会依赖“仓储接口”,“仓储接口”也会依赖“聚合根”,这两者都是除了“实现依赖”之外的依赖关系,如果将“接口”放到“仓储实现”中就丧失了面向接口编程的意义(编译也不会通过),如果放到“独立层”中呢?会编译不通过,出现双向依赖了。

对于类似这种情况下接口,我们将其称为“SPI”,全程为:service provider interface,“SPI”的规则如下:

  1. 概念上更依赖调用方。

  2. 组织上位于调用方所在的包中。

  3. 实现位于独立的包中。

  4. 常见的例子是:插件模式的插件。

“接口”位于“实现方”所在的“包”中

我们先想象一个场景,以Unity提供的IUnityContainer接口为例,除了维护这个框架的团队之外,我们没有发现谁实现了这个接口,虽然理论上是可以实现这个接口的(如果能实现的话,我们何不自己弄额Ioc容器呢?)。

对于类似这种情况下的接口,我们将其称作为“API”,“API”的规则如下:

  1. 概念上更接近实现方。

  2. 组织上位于实现方所在的包中。

  3. 实现和接口在一个包中。

“接口”位于独立的“包”中

这里就不说场景了,如果一个“接口”在一个上下文是“API”,在另一个上下文是“SPI”,那么你就可以这么组织。

需要注意的事项

不管是 SPI 或 API,接口都是可以组织到独立的“包”中,这么做是否有意义,自己来做出决定了。

SPI 和 API 也不一定是接口,我这里都是指狭义的具体的接口。

场景图

66a5de40a2a8431aebda974e58348eb1.png

每一次思考都伴随着收获,也离不开和朋友们的交流,天更蓝了。

SPI 接口:
  1. 定义 :SPI 是一种服务提供者接口,它允许在运行时加载不同的服务实现。

  2. 使用场景 :

  • 模块化设计 :当系统需要高度模块化,且希望将核心功能与具体实现分离时。

  • 可插拔架构 :需要支持多种服务实现,并且可以在不修改代码的情况下替换或增加新的服务实现。

  • 服务发现 :在运行时根据配置或服务注册表动态发现和加载服务。

  • 微服务架构 :在微服务架构中,SPI 可用于服务间的动态交互和集成。

  1. 优点 :

  • 提供了一种机制来在运行时选择和加载服务实现,增加了系统的灵活性和可扩展性。

  • 支持服务的热插拔,无需重启系统即可更换服务实现。

API 接口:
  1. 定义 :API 是一组预定义的函数、协议和工具,用于构建软件应用,它定义了软件组件之间交互的契约。

  2. 使用场景 :

  • 客户端和服务器交互 :当需要设计客户端和服务器之间的通信协议时。

  • 库和框架 :提供给开发者使用的库或框架的公共接口。

  • 第三方集成 :需要与第三方系统或服务进行集成。

  • 内部组件通信 :在大型系统中,不同组件或模块之间的交互。

  1. 优点 :

  • 为开发者提供了清晰的接口文档和规范,易于理解和使用。

  • 有助于保持系统的稳定性,因为 API 变更需要遵循版本控制和兼容性规则。

  • 促进了代码的重用和模块化。

如何选择?

选择使用 SPI 还是 API 的考虑因素:

  • 扩展性 :如果需要在不修改代码的情况下扩展功能,SPI 更合适。

  • 交互性 :API 更适合定义系统内部或系统之间的稳定交互接口。

  • 动态性 :SPI 允许在运行时动态发现和加载服务,而 API 通常在编译时就已经确定。

  • 安全性和稳定性 :API 由于其稳定性和可预测性,通常更受青睐。SPI 虽然灵活,但可能引入运行时错误。

  • 版本控制和兼容性 :API 变更需要考虑版本控制和向后兼容性,而 SPI 可以通过服务版本协商来处理兼容性问题。

架构是“取舍”,而非“银弹”。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,“长按”或“扫描”下方二维码噢:

ce2f7a64458b467755b7fa67f22dd955.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

245a1a10727038d22609ca3209435429.png

50724dfc8b740d5ea0fab26fc68a5972.png6479011af22bf9ccbd03f64f16eca685.png28d9292988c12f82372baa4f5b54a8b7.png74b09205ada8466bf424f047722fa9ed.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
SPI通信的同步与异步:如何在Linux内核中高效使用spi_sync和spi_async(含实战代码示例) 本文深入解析Linux内核中SPI通信的同步与异步机制,重点对比spi_sync和spi_async的工作原理、性能差异及适用场景。通过实战代码示例展示如何高效使用这两种接口,包括传感器数据读取和高速数据采集的实现,帮助开发者优化SPI驱动性能。文章还提供DMA集成、传输管道化等高级优化技巧,以及常见问题排查方法。 阅读详情

相关推荐

MSPM0 SPI模块深度解析:从架构设计到实战配置与优化

串行外设接口(SPI)是嵌入式系统中实现微控制器与外部设备高速通信的核心协议之一。其工作原理基于主从架构和全双工同步串行通信,通过时钟、数据线和片选信号实现高效的数据交换。SPI的技术价值在于其简单性、高速度和灵活性,广泛应用于存储器、传感器、显示屏等外设的连接。在嵌入式开发实践中,深入理解SPI模块的内部架构,如双缓冲FIFO设计,对于实现稳定可靠的数据传输至关重要。本文聚焦于德州仪器MSPM0 G系列微控制器的SPI模块,详细剖析其核心架构、关键寄存器配置,并结合Flash存储器操作等典型应用场景,提供

weixin_33875839的博客 437

架构设计原则:SPI 与 API 该如何选择?

背景第一次听说 SPI 是阅读《软件框架设计的艺术》,以后陆续在 JDBC 和 SpringBoot 中发现了以这种形式组织代码的方式,本文给出为什么要区分 SPI 和 API 的一个思考过程。从面向接口编程说起我们在“调用方”和“实现方”之间引入了“接口”,上图没有给出“接口”应该位于哪个“包”中,从纯粹的可能性上考虑,我们有三种选择:“接口”位于“调用方”所在的“包”中。“接口”位于“实现方”...

架构精进之路 433

我在架构设计和代码开发中的一些常用原则

不管我一生中取得了多大的成功,其主要原因都不是我知道多少事情,而是我知道在无知的情况下自己应该怎么做。我一生中学到的最重要的东西是一种以原则为基础的生活方式,是它帮助我发现真相是什么,并据此如何行动。 ——瑞·达利欧(Ray Dalio) 在日常的开发和设计过程中,大家对技术设计上的一些问题往往会面临很多的选择,不同的人会有不同的选择,每每如此,我都会尝试着问自己:我做出选择和判断背后的原则是什么?经过这么多年的发展,在软件设计过程,目前沉淀下来的原则有很多,但很多情况下,很多原则为了普适性,总结得.

科技D人生 614

Java SPI与API的终极对决

API通常以接口或抽象类的形式出现,定义了一组方法,这些方法由具体的实现类来实现。

赵KK的博客 385

游戏开发实战:如何用旋转矩阵实现2D角色平滑转向(附Unity代码)

本文深入探讨了在Unity游戏开发中,如何运用旋转矩阵原理实现2D角色的平滑转向。文章从核心理论出发,提供了计算目标旋转、实现平滑插值(Lerp与SmoothDamp)的完整C#代码,并解决了与动画系统、物理引擎协同的常见难题,帮助开发者提升游戏操作手感与视觉流畅度。

weixin_29057237的博客 290

硬件电路(22)-TTL和232切换电路

工作中会遇到TTL和232电平的通信的状态,为了实现一种便捷的切换方式,参考了一些文章,提供一种电路方便大家使用。

剑藏锋的博客 1868

从零构建SPI设备驱动:ESP32-S3的硬件抽象层与API设计哲学

本文深入解析ESP32-S3的SPI控制器架构与ESP-IDF框架的硬件抽象层(HAL)设计哲学,探讨如何从零构建高效、灵活的设备驱动。内容涵盖SPI总线初始化、多设备管理、数据传输机制(阻塞、异步、DMA)的性能权衡以及时序优化,为嵌入式外设开发提供实用API设计指导和最佳实践。

e1f2g的博客 951

别再只飞不记了!用CsvView分析你的大疆飞行日志,优化航拍与排查炸机原因

本文详细介绍了如何利用CsvView工具分析大疆无人机的飞行日志,帮助用户优化航拍效率和飞行安全。通过解读飞行日志中的关键数据,如电池性能、飞行轨迹等,用户可以及时发现潜在问题并改进飞行习惯。文章还提供了事故排查方法和进阶分析技巧,适合无人机爱好者和专业飞手。

weixin_42535461的博客 551

ESP32-S3 的 SPI,真的不只是“连个屏幕那么简单

以 ST7789 这类 SPI 屏为例,看起来只是:SPI + GPIO + 刷图异形屏(物理分辨率 ≠ 驱动分辨率)显存偏移DC / CS / RST 多控制线DMA 对齐问题刷屏撕裂。

坏柠的博客 896

汇川EASY系列之以太网通讯(套接字socket做从站)

汇川EASY系列的以太网通讯中的Socket字通讯,不能使用配置的方式实现,只能通过指令完成,本文将详细说明

这是一个长期关注工控行业技术的博客,实现0-1的突破,期待您的关注和留言 3003

APB Timer验证环境搭建——学习笔记(1)

以下为个人学习笔记,如有疏漏,请大家指正补充~~APB Timer是一个简单的下行计数器,包括一个32位计数器和一组比较器,可以实现多种计时功能。包括生成一次性中断或者定时中断。

qq_41651535的博客 1579

Apache ShenYu终极扩展指南:SPI机制与插件架构深度解析

Apache ShenYu作为一款高性能的Java原生API网关,其强大的**扩展性设计**和灵活的**插件架构**让它在微服务治理领域脱颖而出。🚀 通过本文,你将深入了解ShenYu如何通过SPI机制实现动态扩展,以及如何利用插件架构构建企业级API网关。 ## 💡 什么是SPI机制? SPI(Service Provider Interface)是Java提供的一种服务发现机制,它允许

gitblog_01118的博客 825

基于C#通过PLCSIM ADV仿真软件实现与西门子1500PLC的S7通信方法演示

基于C#通过PLCSIM ADV仿真软件实现与西门子1500PLC的S7通信方法演示

Robot_PLC_HMI_Automation 3162

(4)Java SPI &ShardingSphere 实战可插拔细节

Java SPI &ShardingSphere 实战可插拔细节

RichardGeek的博客 1551

【WRF-Chem教程第四期上】运行 WRF-Chem 模型

完整介绍运行 WRF-Chem 模型的详细步骤

WW、forever的博客 3115

Python爬虫实战:利用最新技术高效爬取百度贴吧帖子内容

本文将详细介绍如何使用Python最新技术栈构建一个高效的百度贴吧爬虫,包括requests-html异步请求、BeautifulSoup4解析、数据存储到MongoDB以及应对反爬机制等完整解决方案。文章包含5000余字详细教程和完整代码实现。网络爬虫(Web Crawler)是一种自动获取网页内容的程序,广泛应用于搜索引擎、数据分析和内容聚合等领域。Python凭借其丰富的库生态系统成为爬虫开发的首选语言。贴吧作为中文互联网最大的兴趣社区,包含大量有价值的UGC内容。动态加载内容处理登录状态维持。

2201_76125261的博客 541

JAVA-SPI让框架更优雅

JAVA-SPI让框架更优雅 架构师是做什么的: 负责公司软件系统的技术路线、架构设计、研发工作; 承担从产品需求像技术实现转换的桥梁作用,根据产品规划更新技术架构的研发方向; 参与项目计划评审; 参与需求分析、建模、软件设计评审; 负责组织技术研究和攻坚工作; 负责组织及带领公司内部员工研究与项目相关的新技术; 管理技术架构团队并给项目、产品开发实施团队提供技术支持; 理解项目的业务需求,给出软件系统整体解决方案; 对技术基础架构的相关技术和业务进行培训,指导开发人员开发。 What? **SPI(S

372

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java SPI机制:从原理到实战,解锁动态扩展的核心密码

本文深入解析Java SPI机制,从原理到实践全面剖析。SPI(Service Provider Interface)作为JDK内置的服务发现机制,通过"约定优于配置"实现接口与实现的解耦。文章详细拆解了SPI三要素(接口、实现类、配置文件)和ServiceLoader的工作流程,并通过日志服务案例演示完整实现过程。同时列举了JDBC驱动、SLF4J等工业级应用场景,分析原生SPI的缺陷并给出缓存、容错等优化方案。最后总结了常见问题及解决方案,强调SPI在框架扩展设计中的核心价值。全文涵

what丶k的博客 629

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux SPI子系统深度分析与实践指南

标准化接口:为各种SPI设备提供了统一的驱动模型和编程接口,大大简化了驱动开发流程。通过抽象出spi_masterspi_devicespi_driver等核心数据结构,实现了硬件操作与业务逻辑的分离。跨平台支持:得益于分层架构设计,SPI子系统能够支持多种不同的硬件平台和体系结构,从简单的微控制器到复杂的应用处理器都可以良好运行。性能与灵活性平衡:子系统提供了从简单的字节传输到复杂的DMA操作等多种传输方式,满足不同应用场景的需求。同时,支持同步和异步操作模式,兼顾了响应速度和处理效率。生态系统完善。

X 649

Java SPI机制与Spring Boot实战:从原理到可插拔架构设计

在软件架构设计中,解耦与可扩展性是核心目标。面向接口编程通过定义契约、分离实现,是实现这一目标的关键技术。其原理在于依赖倒置,调用方仅依赖抽象接口而非具体实现,从而降低模块间耦合度。这一思想的技术价值在于提升了系统的灵活性、可维护性和可测试性,使得功能模块能够独立演化。在应用场景上,它广泛应用于驱动加载、日志框架、插件系统等需要动态扩展能力的领域。本文聚焦于Java SPI(Service Provider Interface)机制,它正是这一思想的标准化实现,通过约定优于配置的方式,在JDBC驱动加载、S

weixin_30458043的博客 360

简单实现jdk自带spi机制

SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它 来做服务的扩展发现,简单来说,它就是一种动态替换发现的机制。使用SPI机制的优势是实现解耦, 使得第三方服务模块的装配控制逻辑与调用者的业务代码分离。 项目架构设计分为三个模块 server-api 、server-core、server-main server-api--对外暴露的接口 server-core--暴露接口的具体实现 server-main--demo

因为低调所以牛逼 456
上一篇: 10月面试的兄弟看看吧。。
下一篇: SpringBoot + Flowable并集成ui,写一个请假流程Demo
公众号-芋道源码
博客等级 码龄10年 1634粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值