对于上面的结构,我们来考虑多实现的情况下,该怎么处理?
第一种方式,是在Service中新增一个包,在里面编写新的逻辑,然后修改配置文件,将新实现作为注入对象。
-
Controller
-
Service
-
- ---- 接口在一个包中
-
impl —实现在另一个包里
-
impl2 —新实现在另一个包里
-
Dao
第二种方式,是新增一个Service模块,在里面编写新的逻辑(注意这里的包和原来Service的包不能相同,或者包相同,但是类名不同,否则无法创建类。因为在加载时需要同时加载两个Service模块,如果包名和类名都相同,两个模块的类全限定名就是一样的了!),然后修改配置文件,将新逻辑作为注入对象。
-
Controller
-
Service
-
- ---- 接口在一个包中
-
impl —实现在另一个包里
-
Service2
-
- impl2 —新实现在另一个包里
-
Dao
相对而言,实际第一种方式相对更简单一点,只需要关注包层面。而第二种方式需要关注模块和包两个层面。另外,实际这两种方式都导致了项目中包含了不需要的逻辑代码。因为老逻辑都会被打进包里。
不过,从结构上来看,实际方式二的结构要比方式一的结构更清晰,因为从模块上能区分逻辑。
那有没有办法来结合两者的优点呢?答案是肯定的,而且操作起来也不复杂!
首先将接口和实现独立开,作为一个独立的模块:
-
Controller
-
Service — 接口模块
-
ServiceImpl
-
- impl —实现在另一个包里
-
ServiceImpl2
-
- impl2 —新实现在另一个包里
-
Dao
其次,调整打包配置,ServiceImpl和ServiceImpl2二选一。既然ServiceImpl和ServiceImpl2是二选一,那ServiceImpl和ServiceImpl2的包结构就可以相同。包结构相同了,那调整了依赖以后,依赖注入相关的配置就不需要调整了。调整后,项目结构看起来像这样:
-
Controller
-
Service — 接口模块
-
ServiceImpl
-
- impl —实现在另一个包
-
ServiceImpl2
-
- impl —新实现和老实现在相同的包中
-
Dao
现在,ServiceImpl和ServiceImpl2模块中的包结构、类名都是一样的。那我们还需要接口模块吗?
假设,我们把Service接口模块去掉,结构变成了如下所示:
-
Controller
-
Service1 — 老实现
-
Service2 — 新实现
-
Dao
单纯的通过调整模块依赖,是否能实现Service的多实现?答案显而易见吧?
不使用接口的缺点
上面给出了不使用接口的理由。不过不使用接口并不是完全没有缺点的,主要问题就是在进行多实现的时候,没有一个强接口规范。即不能通过实现接口,借助IDE快速生成框架代码。对于没有实现的接口,IDE也能给出错误提醒。
一个不太优雅的解决是,将原来的模块里的代码拷贝一份到新模块中,基于老代码来实现新的逻辑。
所以,如果一个项目需要多实现、且多实现数量较多(不过一般项目不会有多个实现的),则推荐使用接口。否则不需要使用接口。
总结
–
本文针对「Service层是否需要接口」这个问题,指出需要接口的理由的问题。以及个人对这个问题的观点,希望对大家有一些帮助。
作者:架构思维
toutiao.com/i6882356844245975563
往期精选 点击标题可跳转
美团实习面试:熟悉红黑树是吧?能不能写一下?说一说空间和时间复杂度?
Spring Boot 集成 WebSocket,实现前后端即时通讯,如此简单!
Spring Boot 接口频繁超时,Alibaba 开源 Arthas 精准定位 BUG 问题!
踩坑!Spring 事务方法与非事务方法相互调用 @Transactional 注解失效不回滚?
Spring Boot 中如何实现 Mybatis 逆向工程,你 GET 到了吗?(附源码)
你了解 JDK 8 Stream 数据流效率吗?千万级数据量性能如何?