点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!


链接:toutiao.com/i6882356844245975563

前几天刷头条又刷到了「Service层和Dao层真的有必要每个类都加上接口吗?」这个问题,之前简单回答了一波,给出的观点是「看情况」

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

先来说说为什么使用了依赖注入框架以后,可以不使用接口!

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

  • 可以在尚未实现具体Service逻辑的情况下编写上层代码,如Controller对Service的调用

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

  • 可以对Service进行多实现

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

先说说第一个理由:「上层可以在下层逻辑没有实现的情况下进行编码」!很典型的面向接口编程,对层与层之间进行了解耦,看起来好像没有问题。

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

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

如果开发人员想在下层逻辑没有完成的情况下,先开发上层逻辑,可以先编写下层类的空方法来先完成上层的逻辑。

这里推荐一个个人比较喜欢的开发流程,自上向下的编码流程:

  • 先在Controller层编写逻辑,遇到需要委托Service调用的地方,直接先写出调用代码。

  • 优先完成Controller层的流程

  • 然后使用IDE的自动补全,对刚才调用下层的代码生成对应的类和方法,在里面添加TODO

  • 等所有的类和方法都补全了,再基于TODO,按照上面的流程去一个个的完善逻辑。

  • 此方法可以使你对业务流程有比较好的理解。

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

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

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

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

  • Controller

  • Service

  • Dao

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

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

  • Controller

  • Service

    • --- 接口在一个包中

    • impl --- 实现在另一个包里

  • Dao

对于上面的结构,我们来考虑多实现的情况下,该怎么处理?

第一种方式,是在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层是否需要接口」这个问题,指出需要接口的理由的问题。以及个人对这个问题的观点,希望在评论区写出自己的理解 !

热门内容:
  • 你还在认为 count(1) 比 count(*) 效率高?

  • 写了个牛逼的日志切面,甩锅更方便了!

  • 看看人家那后端API接口写得,那叫一个优雅!

  • Spring Boot 监听 Redis Key 失效事件实现定时任务

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡

http://www.taodudu.cc/news/show-122265.html

相关文章:

  • 必须了解的 MySQL 三大日志
  • jar包又冲突了?如何快速确定与哪个jar包冲突?
  • 面试官扎心一问:知道 CopyOnWriteArrayList 吗?
  • 自从上线了 Prometheus 监控告警,真香!
  • 卸载Notepad++!事实已证明,它更牛逼……
  • 教你如何通过分析GC日志来进行JVM调优
  • 一个 SpringBoot 项目该包含哪些?
  • 非常有必要了解的Springboot启动扩展点
  • 星巴克不使用两阶段提交
  • 怎么去掉 IDEA 中 XML 显示的屎黄色
  • 后端必备 Git 分支开发:规范指南
  • 如何优雅的转换 Bean 对象!
  • 你还在用Swagger?试试这个神器!
  • 硬刚一周,3W字总结,一年的经验告诉你如何准备校招!
  • SpringCloud 之 Zuul 网关搭建及配置
  • 从CPU缓存看缓存的套路
  • 如何设计日志采集系统?不妨看看这篇文章
  • SpringBoot最最最常用的注解梳理
  • 关于Redis缓存,这3个问题一定要知道!
  • Java接地气日常编码技巧
  • 震惊 Guava 竟然有坑
  • 通用的底层埋点都是怎么做的?
  • Prometheus 如何做到“活学活用”,大牛总结的避坑指南
  • Java生鲜电商平台-监控模块的设计与架构
  • 如何让 Mybatis 自动生成代码,提高开发效率
  • Oracle慌了!华为终于对JDK下手了!
  • Spring官方都推荐使用的@Transactional事务,为啥我不建议使用!
  • 10大黑客专用的 Linux 操作系统,每个都很酷!
  • 如何设计一个通用的权限管理系统
  • 说实话,去一家小公司从 0 到 1 搭建后端架构,真难~

讨论:Service层需要接口吗?相关推荐

  1. CTO说:Service层的接口是不是多此一举

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:架构思维 来源:toutiao.com/i68823 ...

  2. Service层需要接口吗

    Service层需要接口吗 1 不需要接口的理由 2 项目结构与接口实现 3 不使用接口的缺点 原文链接:https://www.toutiao.com/article/688235684424597 ...

  3. 为什么要用impl继承service层_讨论:Service层需要接口吗?

    阅读本文大概需要 5 分钟. 前几天刷头条又刷到了「Service层和Dao层真的有必要每个类都加上接口吗?」这个问题,之前简单回答了一波,给出的观点是「看情况」现在结合我参与的项目以及阅读的一些项目 ...

  4. springboot中service层注入的是实现类,但Controller层接收的是接口

    我们习惯这样编写代码: 在service层写接口,然后用实现类去实现接口,并且将实现类注入到容器中 @Service public class AccountServiceImpl implement ...

  5. 为什么要用impl继承service层_JavaWeb service层 dao层 采用接口+impl 的原因

    service层 采用接口+impl : 是为了应对可能不同情形下,会存在多套业务逻辑.在调用的时候,根据实际情况去调用对应的serviceImpl eg: 存在 serviceImp1, servi ...

  6. 聊一聊:Service层你觉得有用吗?

    前段日子在社群(点击加入)里看到有人讨论关于Service层接口的问题,DD也经常碰到周围的新人有问过一些类似的问题:一定要写个Service层的接口吗?Service层的接口到底用做什么用的呢?好像 ...

  7. service 层注入不同的数据源_.NET 理论基础+实战控制台程序实现AutoFac注入

    (给DotNet加星标,提升.Net技能) 转自:在7楼 cnblogs.com/RayWang/p/11128554.html 简介 该系列共5篇文章,旨在以实战模式,在.NET下的 控制台程序 F ...

  8. service 层 拼接的html 代码如何直接返回_字符串拼接,会走StringBuilder 吗?

    前言 最近在突然想到了String字符串拼接问题,于是做了一个demo测试了一下,到底String类型的字符串在拼接的时候,哪种情况下会走会走StringBulider进行字符串拼接,而哪种情况编译器 ...

  9. websocket连接mysql_websocket 使用 spring 的service层 ,进而调用里面的 dao层 来操作数据库 ,包括redis、mysql等通用...

    1.前言 描述一下今天用websocket踩得坑  --->空指针异常! 我想在websocket里面使用service 层的接口,从中获取数据库的一些信息  , 使用 @Autowired 注 ...

最新文章

  1. ASP.NET设置数据格式与String.Format使用总结
  2. Python偏相关(Partial Correlation)或者部分相关性系数计算实战:偏相关性(Partial Correlation)计算及结果解读
  3. NOIP2018 赛前集训总结反思
  4. Android23版本以上删除HttpClient的解决办法
  5. [SonarQube]Scanners内存溢出
  6. 【Python】CentOs7 Python3安装Openssl以及解决ssl问题
  7. 机械加工工艺师手册_机械加工中车、刨、铣、镗、磨、钻、线切割等设备,你知道哪些?...
  8. input accept属性控制选择文件类型
  9. 快速解决Ubuntu无法访问Windows分区的问题
  10. ppt五种经典字体组合
  11. 计算机休眠唤醒原理,电脑休眠和睡眠区别以及怎么唤醒
  12. 回归中的相关度和R平方值——学习笔记
  13. 在Qt中使用OpenGL(三)
  14. fzu 1891 升降序列
  15. git命令提交后push失败,缺少changeID的解决办法
  16. 漫画:什么是蓝绿部署?
  17. .Net自动生成BH
  18. Android平台 Target API level 升级到 31,在Android 12上启动黑屏卡死
  19. 【Linux】IRQ
  20. 多模态视频商品检索记录再刷新!第二届淘宝直播算法大赛完美落幕

热门文章

  1. hook NtTerminateProcess进行应用的保护
  2. python xml模块学习
  3. mem 族函数的实现
  4. 应用内设置语言不重启方法
  5. 【算法】弗洛伊德(Floyd)算法
  6. 数据结构与算法分析(C++版)(第二版)
  7. ssl 和 https
  8. 凌亮:动手学数据分析笔记
  9. 【Whalepaper】CV论文研读 - Involution内卷:超越Convolution的新算子
  10. 【青少年编程】全国青少年软件编程等级考试大纲与说明(Scratch)