⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/6931635085863190536 「JackWu」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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

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

抽象和解耦

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

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

好的抽象

JDK中就有很多抽象,比如最常用的List<E>Map<K, V>。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缓存。

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

最后

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

文章目录
  1. 1. 抽象和解耦
  2. 2. 好的抽象
  3. 3. 业务开发中的接口
  4. 4. 中间件的抽象
  5. 5. 最后