博客
关于我
Service 层需要实现接口吗?
阅读量:796 次
发布时间:2023-03-22

本文共 2281 字,大约阅读时间需要 7 分钟。

Service 层是否需要接口?

最近在技术交流群里看到一个有趣的问题:“Service 层是否需要接口?”这个问题引发了不少讨论。不少人认为需要接口,而我则简单地回答了一些,看起来像这样:

Service 层是否需要接口?

初步观点:看情况

最近在技术交流群里看到一个有趣的问题:“Service 层是否需要接口?”这个问题引发了不少讨论。不少人认为需要接口,而我则简单地回答了一些,看起来像这样:

初步观点:看情况

前几天看技术交流群的话题,又刷到了「」这个问题,之前简单回答了一波,给出的观点是「看情况」

结合项目实际:不需要接口!

结合我参与的项目以及阅读的一些项目源码来看,如果项目中使用了像 Spring 这样的依赖注入框架,那可以不用接口!让我详细说说为什么。

为什么使用依赖注入框架可以不用接口?

我整理了支持 Service 层和 Dao 层需要加上接口的理由,总结下来就这么三个:

  • 可以在尚未实现具体 Service 逻辑的情况下编写上层代码,如 Controller 对 Service 的调用
  • Spring 默认是基于动态代理实现 AOP 的,动态代理需要接口
  • 可以对 Service 进行多实现
  • 这三个理由都站不住脚!

    其实,这三个理由都站不住脚!

    理由一:上层可以在下层逻辑没有实现的情况下进行编码

    “上层可以在下层逻辑没有实现的情况下进行编码”!很典型的面向接口编程,对层与层之间进行了解耦,看起来好像没有问题。

    这种开发方式适合不同模块之间是由不同的人或项目组开发的,因为沟通的成本比较大。同时避免由于项目组之间开发进度的差异而相互影响。

    不过让我们回想一下,在一般项目开发里面,有多少项目组是按层来切分开发任务的呢?实际上,大部分的项目都是按照功能划分的。即使是现在前后端分离的情况,单纯的后端开发也是按照功能模块进行任务划分,即一个人负责从 Controller 层到 DAO 层的完整逻辑处理。在这种情况下,每一层都先定义一个接口,再去实现逻辑,除了增加了开发人员的工作量(当然,如果代码量计入工作量的话,那开发人员应该也不是太排斥接口的!),实际没有任何用处。

    理由二:Spring 默认是基于动态代理实现 AOP 的,动态代理需要接口

    这个理由完全不成立。Spring 默认是基于动态代理实现 AOP 的,不过通过配置是可以使用 CGLib 来实现 AOP。CGLib 是不需要接口的。

    理由三:可以对 Service 进行多实现

    这个理由不充分,或者说没有考虑场景。实际上在大多数情况下是不需要多实现,或者说可以使用其它方式替代基于接口的多实现。

    接口的实际意义

    对于很多使用了接口的项目,项目结构也是有待商榷的!下面,我们结合项目结构来说明。

    项目结构的优化

    一般项目结构都是按层来划分的,如下所示:

    Controller
    ├── Service
    ├── Dao

    对于不需要多实现的情况,也就不需要接口了。上面的项目结构即可满足要求。

    对于需要多实现的情况,无论是现在需要,还是后面需要。这种情况下,看起来好像是需要接口。此时的项目结构看起来像这样:

    Controller
    ├── Service
    ├── Dao
    └── Service-Impl
    ├── Service-Impl-1
    ├── Service-Impl-2
    └── Service-Impl-3

    不过这种结构反而变得复杂了。

    优化项目结构

    其实,我们可以采取一种更高效的方式来实现多实现:

  • 接口模块:将接口和实现分离成一个独立的模块:
  • Controller
    └── Service
    ├── Service-Impl
    └── Service-Impl-2
    1. 模块化打包:调整打包配置,ServiceImpl 和 ServiceImpl2 二选一。由于 ServiceImpl 和 ServiceImpl2 是二选一,那 ServiceImpl 和 ServiceImpl2 的包结构就可以相同。包结构相同了,那调整了依赖以后,依赖注入相关的配置就不需要调整了。调整后,项目结构看起来像这样:
    2. Controller
      └── Service
      ├── Service-Impl
      └── Service-Impl-2

      优化后的优点

    3. 结构清晰:这种方式下,项目结构更加清晰,模块之间的关系更明确。
    4. 减少冗余:无需在项目中引入额外的接口模块,减少了不必要的代码。
    5. 灵活性:当需要新增实现时,只需要在模块中添加新的类即可,无需修改配置文件。
    6. 不使用接口的缺点

      不过,不使用接口也不是没有缺点的,主要问题就是在进行多实现的时候,没有一个强接口规范。也就是说,不能通过实现接口,借助 IDE 快速生成框架代码。对于没有实现的接口,IDE 也能给出错误提醒。

      优化后的开发流程

      对于这种情况,我推荐一种更高效的开发流程:

    7. 自上而下的编码流程
    8. 1. 先在 Controller 层编写逻辑,遇到需要委托 Service 调用的地方,直接先写出调用代码。
      2. 使用 IDE 的自动补全,对刚才调用下层的代码生成对应的类和方法,在里面添加 TODO。
      3. 等所有的类和方法都补全了,再基于 TODO,按照上面的流程去一个个的完善逻辑。

      这种方法可以让你对业务流程有比较好的理解。

      总结

      本文针对「Service 层是否需要接口」这个问题,指出需要接口的理由的问题。以及个人对这个问题的观点,希望在评论区写出自己的理解!

    转载地址:http://jsqfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现离散傅立叶逆变换 IDFT算法(附完整源码)
    查看>>
    Objective-C实现离散傅里叶变换(附完整源码)
    查看>>
    Objective-C实现离散数学真值表(附完整源码)
    查看>>
    Objective-C实现移位密码加解密(附完整源码)
    查看>>
    Objective-C实现程序暂停(附完整源码)
    查看>>
    Objective-C实现程序等待一段时间(附完整源码)
    查看>>
    Objective-C实现程序自动更新(附完整源码)
    查看>>