前几天刷到个问题:Service 层和 Dao 层真的有必要每个类都加上接口吗?这个问题之前简单回答了一波,给出的观点是看情况!今天我们要探讨的问题是:Service 层需要接口吗?

现在结合我参与的项目以及阅读的一些项目源码来看。如果项目中使用了像 Spring 这样的依赖注入框架,那可以不用接口!
先来说说为什么使用了依赖注入框架以后,可以不使用接口!
不需要接口的理由
我整理了支持 Service 层和 Dao 层需要加上接口的理由,总结下来就这么三个:
可以在尚未实现具体 Service 逻辑的情况下编写上层代码,如 Controller 对 Service 的调用。
Spring 默认是基于动态代理实现 AOP 的,动态代理需要接口。
可以对 Service 进行多实现。
先在 Controller 层编写逻辑,遇到需要委托 Service 调用的地方,直接先写出调用代码。优先完成 Controller 层的流程。
然后使用 IDE 的自动补全,对刚才调用下层的代码生成对应的类和方法,在里面添加 TODO。
等所有的类和方法都补全了,再基于 TODO,按照上面的流程去一个个的完善逻辑。
项目结构与接口实现
Controller
Service
Dao
对于不需要多实现的情况,也就不需要接口了。上面的项目结构即可满足要求。
对于需要多实现的情况,无论是现在需要,还是后面需要。这种情况下,看起来好像是需要接口。
Controller
Service
----接口在一个包中
impl ---实现在另一个包里
Dao
如下所示:
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
Controller
Service1 --- 老实现
Service2 --- 新实现
Dao
单纯的通过调整模块依赖,是否能实现 Service 的多实现?答案显而易见吧?
不使用接口的缺点
上面给出了不使用接口的理由。不过不使用接口并不是完全没有缺点的,主要问题就是在进行多实现的时候,没有一个强接口规范。
即不能通过实现接口,借助 IDE 快速生成框架代码。对于没有实现的接口,IDE 也能给出错误提醒。
一个不太优雅的解决是,将原来的模块里的代码拷贝一份到新模块中,基于老代码来实现新的逻辑。
所以,如果一个项目需要多实现、且多实现数量较多(不过一般项目不会有多个实现的),则推荐使用接口。否则不需要使用接口。
总结
本文针对 Service 层是否需要接口这个问题,指出需要接口的理由的问题。以及个人对这个问题的观点,希望对大家有一些帮助。

关注HarmonyOS技术社区,回复【鸿蒙】送定制T恤(礼品不多,先到先得),还可以免费下载鸿蒙入门资料!
👇扫码立刻关注👇

专注开源技术,共建鸿蒙生态
编辑:陶家龙
出处:toutiao.com/i6882356844245975563

精彩文章推荐:
瞧瞧,人家那后端API接口写得多优雅!MariaDB性能优化,我终于搞清楚了!为什么我不建议在Docker中部署数据库?




