SPI and API
目录
背景从面向接口编程说起“接口”位于“调用方”所在的“包”中“接口”位于“实现方”所在的“包”中“接口”位于独立的“包”中需要注意的事项另外一张图备注
背景返回目录
第一次听说 SPI 是阅读《软件框架设计的艺术》,以后陆续在 Log4Net 和 Quartz.Net中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一个思考过程。
从面向接口编程说起返回目录

我们在“调用方”和“实现方”之间引入了“接口”,上图没有给出“接口”应该位于哪个“包”中,从纯粹的可能性上考虑,我们有三种选择:
- “接口”位于“调用方”所在的“包”中。
- “接口”位于“实现方”所在的“包”中。
- “接口”位于独立的“包”中。
下面让我们依次分析这三种可能性,如果现实中确实有这种可能性,不如我们就为其起个名字以方便交流。
“接口”位于“调用方”所在的“包”中返回目录
我们先想象一个场景,以仓储的接口为例:

我们将“仓储接口”放置于“领域层”这个“包”中,实现放在一个独立的“包”中,我们看DDD大师的实现都是这样子,现在来思考一下为什么这么做。
“领域层”的“领域服务”会依赖“仓储接口”,“仓储接口”也会依赖“聚合根”,这两者都是除了“实现依赖”之外的依赖关系,如果将“接口”放到“仓储实现”中就丧失了面向接口编程的意义,如果放到“独立层”中呢?会编译不通过,出现双向依赖了。
对于类似这种情况下接口,我们将其称为“SPI”,全程为:service provider interface,“SPI”的规则如下:
- 概念上更依赖调用方。
- 组织上位于调用方所在的包中。
- 实现位于独立的包中。
- 常见的例子是:插件模式的插件。
“接口”位于“实现方”所在的“包”中返回目录
我们先想象一个场景,以Unity提供的IUnityContainer接口为例,除了维护这个框架的团队之外,我们没有发现谁实现了这个接口,虽然理论上是可以实现这个接口的(如果能实现的话,我们何不自己弄额Ioc容器呢?)。
对于类似这种情况下的接口,我们将其称作为“API”,“API”的规则如下:
- 概念上更接近实现方。
- 组织上位于实现方所在的包中。
- 实现和接口在一个包中。
“接口”位于独立的“包”中返回目录
这里就不说场景了,如果一个“接口”在一个上下文是“API”,在另一个上下文是“SPI”,那么你就可以这么组织。
需要注意的事项返回目录
不管是SPI或API,接口都是可以组织到独立的“包”中,这么做是否有意义,自己来做出决定了。
SPI和API也不一定是接口,我这里都是指狭义的具体的接口。
另外一张图返回目录

备注返回目录
每一次思考都伴随着收获,也离不开和朋友们的交流,天更蓝了。
SPI and API的更多相关文章
- 设计原则:小议 SPI 和 API
背景 第一次听说 SPI 是阅读<软件框架设计的艺术>,以后陆续在 Log4Net 和 Quartz.Net中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一 ...
- Java SPI 和 API,傻傻分不清?
最近新写了一个中间件「运行时动态日志等级开关」,其中使用Java SPI机制实现了自定义配置中心,保证良好的扩展性. 项目地址,走过路过可以点个star :)https://github.com/sa ...
- JAVA—API和SPI概念
JAVA—API和SPI概念 目录 概念 JDBC实例 自己实现一个SPI 总结 概念英文: What is the difference between Service Provider Inter ...
- Java:Spi 小实战
背景 Java 中区分 Api 和 Spi,通俗的讲:Api 和 Spi 都是相对的概念,他们的差别只在语义上,Api 直接被应用开发人员使用,Spi 被框架扩张人员使用,详细内容可以看:http:/ ...
- 02_dubbo的SPI
[dubbo为什么不采用JDK自带的SPI] 1.JDK自带的SPI(ServiceLoader)会一次性实例化扩展点所有实现,基本只能通过遍历全部获取,也就是接口的实现类全部加载并实例化一遍,如果我 ...
- 深入理解 Java 中 SPI 机制
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5A作者:姜柱 SPI(Service Provider ...
- Java SPI详解
1.什么是SPI SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件. SPI的作用就是为这些被扩展的 ...
- spi-mem: 为SPI存储器生态带来一些一致性
在本文中,我们将介绍关于spi-mem Linux内核框架的工作,该框架将允许在SPI NOR设备和常规SPI设备以及SPI NAND设备上复用SPI控制器驱动程序. 从SPI到双线.四线.八线SPI ...
- 什么是JDK的SPI机制
什么是SPI和API Application Programming Interface (API)? The API is the description of classes/interfaces ...
随机推荐
- mysql_navicat-permium 在Mac下破解方法
首先下载符合当前系统支持的navicat-permium版本,我自己下载的是11.0.16 然后我们开始破解旅程,先要安装上navicat-permium,记住千万不要打开(如果你打开了不好意思,卸了 ...
- 【Swift】沙盒缓存
本地sandbox缓存目录 沙盒の 主目录: po NSHomeDirectory() /Users/SpongeBob/Library/Developer/CoreSimulator/D ...
- 让Docker功能更强大的10个开源工具
让Docker功能更强大的10个开源工具 更好的管理.Web前端程序.更深入地了解容器应用程序,Docker生态系统正在迅速发展,这还得归功于其充满活力的开源社区. 软件项目的成功常常根据其催生的生态 ...
- HDU 5001 概率DP || 记忆化搜索
2014 ACM/ICPC Asia Regional Anshan Online 给N个点,M条边组成的图,每一步能够从一个点走到相邻任一点,概率同样,问D步后没走到过每一个点的概率 概率DP 測 ...
- C#中如何获取系统环境变量
原文:C#中如何获取系统环境变量 C#中获取系统环境变量需要用到Environment Class.其中提供了有关当前环境和平台的信息以及操作它们的方法.该类不能被继承. 以下代码得到%systemd ...
- 如何把一个c语言程序做成windows服务开机自启动
原文:如何把一个c语言程序做成windows服务开机自启动 目前写的程序是一个用c语言实现socket侦听的,那么如何把这个程序做成开机自启动呢? 我们是通过vs6.0,编译后生成了.exe文件,然后 ...
- orleans开篇之hello world
orleans开篇之hello world 什么是orleans Orleans是一个建立在.NET之上的,设计的目标是为了方便程序员开发需要大规模扩展的云服务.Orleans项目基本上被认为是并行计 ...
- (12) MVC5 EF6 Bootstrap3
MVC5 + EF6 + Bootstrap3 (12) 新建数据 系列教程:MVC5 + EF6 + Bootstrap3 上一节:MVC5 + EF6 + Bootstrap3 (11) 排序.搜 ...
- [转载]C#播放流媒体的几种方法
做视频开发要学的东西真多,不知道如何入门,乱打乱撞,慢慢摸索吧! 首先搭建Windows Meida Server ,方法很简单,试试就会.在这里需要声明的是,这几种方法 都可以播放 本地视频.并且基 ...
- ASP.NET 5 Overview
ASP.NET 5概观 (ASP.NET 5 Overview) http://www.asp.net/vnext/overview/aspnet-vnext/aspnet-5-overview AS ...