Service 层和 Dao 层有必要为每个类都加上接口吗?
以下文章来源方志朋的博客,回复”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层是否需要接口」这个问题,指出需要接口的理由的问题。以及个人对这个问题的观点,希望对大家有一些帮助。
热门内容:硬核分享,靠这个技术过了阿里二面!
5种分布式事务最终一致性解决方案,一次性说清了!
拜访了这位小哥的GitHub后,我失眠了!
我们已经不用AOP做操作日志了!
强烈不建议你用 a.equals(b) 判断对象相等!
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡
Service 层和 Dao 层有必要为每个类都加上接口吗?相关推荐
- 在 Java Web 项目中,Service 层和 Dao 层真的有必要每个类都加上接口吗
作者 l 会点代码的大叔(CodeDaShu) 很多程序员在刚开始工作的时候,接触到的项目都是这样做的:项目的代码被分成 Controller.Service.Dao 层,一个接口对应一个实现类,然后 ...
- java action dao_java中Action层、Service层和Dao层的功能区分
一.Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DA ...
- [转]JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类.Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操 ...
- 关于service层、dao层,以及O/R Mapping之间的思考
部门最近正式进入oo的开发,采用了类似于petshop4的层次结构,简单来说,service层调用dao(当然是用配置文件+反射的方式),dao通过ibatis.net完成从数据库中的table到do ...
- 框架学习(1)——service层,dao层和service实现类进行数据库操作
最近也是比较忙,也只能忙里偷闲地抓紧时间接着学习一下技术,自从上次学习了maven之后,越来越对框架产生了兴趣,下了好多的spring视屏,听着老师的建议,最近也萌生了看别人的代码进行学习的想法,然后 ...
- pojo层、dao层、service层、controller层的作用
pojo层(model) 实体层 数据库在项目中的类 model是模型的意思,与entity.domain.pojo类似,是存放实体的类. 类中定义了多个类属性,并与数据库表的字段保持一致,一张表对应 ...
- java sdi接口是什么意思_JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类.Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操 ...
- Action层, Service层 ,modle层 和 Dao层的功能区分【和语言无关,只是为了了解这几个层是干什么的】
来源:http://www.xuebuyuan.com/2153333.html Action主要的功能就是组织service的,比如你要做权限验证,那么请求会被Action获取,那么如何验证呢?A ...
- SSM框架中各层的含义和联系(Pojos层、Dao层、Service层、Action层......)
一.pojo层 即Plain Ordinary Java Object,也有人称其为model.domain.bean等,pojo层是对应的数据库表的实体类. 二.1.持久层:Dao层(Mapper) ...
最新文章
- Pythorch使用总览
- Nutanix助力五矿证券迈向金融混合云2.0
- .NET中书写XML的一种简单方法
- 【逆水寒三周年】大型MMO项目UI管理的价值与责任
- Ubuntu识别USB设备
- 硬件知识:电脑硬盘的数据保护与恢复,新手必备的知识!
- 国科大prml15-BP
- cron 12点执行_【技术指南】Crontab调度重复执行的任务
- Lamda和kappa架构
- Ubuntu16.04下部署 nginx+uwsgi+django1.9.7(虚拟环境pyenv+virtualenv)
- SEO能给独立站系统带来巨大的搜索流量吗?
- 【leetcode】963. Minimum Area Rectangle II
- 如何成为一名卓越的数据科学家 ——七剑之一:问题定义
- vue给div绑定keyup的enter事件实现接电话(结合阿里云软电话SDK)
- 国内几款接口管理平台,使用体验分析对比:总有一款是你想要的!
- 睡眠质量不好怎么改善,这些助眠好物让你失眠快速入睡
- 机器学习中的模型是什么?
- Winsock中accept函数获取到的ip地址一直为204.204.204.204或0xcccccccc的解决方案
- javascript开源电子表格
- 游戏感:虚拟感觉的游戏设计师指南——第十三章 超级马里奥兄弟