接触java后,各种书籍、文章、平台都在强调面向接口开发的重要性。在工作中,用的最多的可能是定义IService接口,然后ServiceImpl实现,但再写了大量这样的代码后,好像并没有体会到这样的接口有什么特别的优点。

可能很多接触java的朋友,都或多或少的有上面的这种感觉,感觉面向接口好像是解耦了,但这种解耦好像又没有什么太大的意义。结合实际开发,来总结下自己的一些认识。

抽象和解耦

编程领域中,非常重要的两个概念, 抽象和 解耦,这也就是面向接口开发要达到的效果。

文章开头提到的那种接口方式,95%的场景其实是没有意义的,通常项目中service层的业务,其实是没有抽象的必要的。因为service是为web接口提供具体业务能力的,简单的web接口可能就是对参数进行一下传递,直接调用service实现就可以,所以说95%的抽象其实是没有太大意义的。

好的抽象

JDK中就有很多抽象,比如最常用的ListMap。Map是一个接口,基于Map接口的抽象实现有HashMap/TreeMap/Hashtable/SortedMap,Map就是一个抽象,它定义了Map类型的数据应该有的能力,如:get/put/remove/putAll/clear等等,但同样的接口方法,不同的实现类有不同的特性,比如是否允许key为null,这里就不细说了。

有了Map的抽象,定义了统一的数据结构:只要是Map类型的对象,大家都知道get/put/remove等方法的功能是一样的,如果没有这层抽象,同样一个put功能,不同的实现是不同的人开发的,可能会有很多不同的名字put/add/set/input等等,这就会对使用这造成困扰。

业务开发中的接口

像底层的工具和代码,都是运用了大量的抽象,但在业务开发中似乎不需要这种过于严谨的抽象,那面向接口开发对于业务开发还有意义吗?

有意义!!!

上面说的service的抽象感觉很没有必要,但为了防止项目发展的过程中有这样的需要,所以基本上所有的项目,也按照接口和接口实现的方式开发,这是其中一方面。

还有运用最多的地方就是RPC接口,RPC接口就是把业务服务抽取出一个API module,在这个modle中只定义接口、入参和出参。需要调用服务的RPC只需要引用这个API module,两个服务间约定好入参和出参,消费方不需要关注接口是如何实现的,不管生产者的实现如何升级,只要约定的接口不变,消费方就不需要有任何变化。这就利用接口,完成了解耦。如果不用接口进行解耦,那么每次生产者的内部逻辑调整,消费方就要配合升级,这无疑是噩梦。

中间件的抽象

项目在开发的过程中,会用到各种中间件技术,比如:缓存、数据库、文件服务器、mq等,这些中间件在随着项目的发展,不可避免的会出现技术选型更换的情况。如文件服务器可选的有:FastDFS、minio、阿里SSO、ftp文件服务器等,可能随着业务的发展,在项目初期选择的中间件产品已经不适用了,需要更换新的技术产品,如果没有进行抽象和解耦设计,将调用中间件的具体实现混杂在业务代码中,将是非常难以更换的。

这就可以利用接口进行抽象,比如文件服务器,虽然有各种各样的产品,但在上传文件时这些参数一般是通用的,如: 文件流、文件名称、保存路径等,如果用到SSO产品可能还有桶的概念。将文件上传的功能抽象为接口,利用spring framework的依赖注入特性,业务层只需要关注接口,而不用关心具体的实现类。这样,在更换技术产品的时候,就能在不影响业务的情况下,完成技术产品的替换。

同理,ORM框架通过一层接口抽象,就可以在对业务代码毫无影响的情况下,使用 Mybatis或者 JPA等ORM框架。缓存通过接口抽象后,也可以选择使用 本地缓存或者 Redis缓存。

目的只有一个,将业务实现与中间件调用实现解耦。

最后

抽象、解耦,以及接口的使用,远远不止这些。这些只是个人工作期间的一些简单的思考,在这里分享一下,如果有什么不正确的理解欢迎大家指正。

福利

IT架构师/技术大咖的交流圈子,为您提供架构体系知识、技术文章、流行实践案例、解决方案等,行业大咖分享交流/同行经验分享互动,期待你的加入!扫码即可加入哦

随着材料不断增多社群会不定期涨价早加入更优惠

公众号发送如下关键字获取免费资料:

1.架构电子书视频--回复"架构"

2.架构实践案例集--回复"实践"

3.Docker实战文档--回复"docker"

4.技术架构规划文档--回复"规划"

5.华为鸿蒙技术资料--回复"华为"

免责声明:

本号部分分享的资料来自网络收集和整理,所有文字和图片版权归属于原作者所有,且仅代表作者个人观点,与本号无关,文章仅供读者学习交流使用,并请自行核实相关内容,如文章内容涉及侵权,请联系后台管理员删除。