作者 l 会点代码的大叔(CodeDaShu)

很多程序员在刚开始工作的时候,接触到的项目都是这样做的:项目的代码被分成 Controller、Service、Dao 层,一个接口对应一个实现类,然后就一直保持了这个习惯,但是可能并没有考虑过为什么要这么做,或者并没有想过这么做的好处是什么。

从工程化的角度来看,面向接口的编程是很有必要的,不过我们还是要结合实际情况来考虑。

01

依赖倒置和解耦

“如果实现类可能会变化,那么最好使用面向接口编程,让每一层代码解耦,减少后期的修改工作量。”

依赖倒置、解耦确实是面向接口编程的优势之一,比如我们要实现一个给用户发送短信的功能:

  • 项目刚开始的时候,公司买了阿里云的服务,直接调用阿里云的一个接口进行短信发送;

  • 项目运行一段时间,又改成和腾讯云合作,那么发送短信的代码就需要修改;

  • 为了避免领导说“再改回去吧”,这里写一个接口、两个实现,上层方法只面向接口编写,就会方便很多。

不过,这一切都是我们“假想”出来的,但后期真的会变化么?

至少我工作十多年,几乎没见过这种变来变去的需求,提到 Dao 层增加接口,通常开发人员最爱说的就是:“避免项目做数据库迁移,原来使用 Oracle 现在要换成 MySQL”,那这种事情会经常发生么?

02

接口等于规范

“接口相当于一个标准、一个规范,制定接口的人和实现接口的人,可能不是同一拨人。”

这个说法也没有错,通常这种情况确实适合使用面向接口的编程,比如 JDBC 的实现:

  • Oracle 公司(之前的 Sun)提供 JDBC 标准(接口)。

  • 各个数据库厂商提供针对自家数据库的实现。

  • 我等码农在 Java 中敲代码访问数据库。

这时候接口制定、接口实现和接口使用就是不同的人;但是如果在同一个项目中呢?

  • 如果项目是一个人开发的,那不用说,接口制定、实现和使用都是一个人,这时候还费这劲儿干啥;

  • 我们大多数项目,接口类和实现类都是一个人来做的,很少有项目是领导把接口写好,然后说“各位小弟,实现类就看你们的了”;

  • 那么实现和使用的人呢?大部分时候也是同一个人,但也有例外,比如一个需求设计两个功能模块的修改,A 模块的开发要用 B 模块的一个功能,这时候可以 B 模块的开发把接口先定好,这样 A 和 B 就可以同时开发了;

  • 当然 B 模块的开发也可以先写一个空方法:方法名称、入参和出参都制定好,中间没有逻辑,然后先提交一版,这样 A 模块的开发就可以快乐地 new() 了;不过我不太建议这样做的原因是:通常开发 commit 一次,提交的内容应该是完整的。

03

面向接口的编程

那么既然我们的项目中,接口和实现类通常是一一对应的,而且开发的人也是同一个人,又没有更换实现类的可能,那么还有必要面向接口编程么?

有一些情况是必须使用接口的,比如:

  • 如果你的业务需要通过 RPC 的方式暴露给其他系统调用,这时候接口是有必要的,调用方只关注接口,不关心你的实现类,也不会因为你的实现类变更而受到影响;

  • 测试驱动开发,在具体的实现类完成之前,需要先根据结构编写测试用例;

  • 现在有些框架只需要开发人员写结构了,比如 Spring Data JPA、Feign 等等;

再去掉这些必须使用接口的情况,那还必须要遵守“一个接口一个实现类”的写法么?我建议还是需要的。

当你带领一个团队的时候,可能这个团队并不大,只有三五个开发人员,但是随着项目的推进迭代,如果没有使用面向接口开发的话,你会惊奇地发现,项目的代码越来越复杂、越来越乱,一个类有几十个方法,一个方法有几百行代码,新来的组员看的一头雾水,甚至你这个项目经理都不想看其中的代码;

不要提什么制定代码规范,规范一直都在,但是总有人不遵守,防是防不住的;

如果项目的 Service 层和 Dao 层,都是接口-实现类这样做的,大多数时候代码还是可以看的,相当于多了一个方法目录,比如可以让开发人员在写一个新方法之前,看看能不能复用之前的方法;当然,你不这么做的话,开发人员也可以直接在实现类中看现有的方法,只是相对来说,在一个几十上百行的目录中翻找,和在一个成千上万行的实现类的实现类中翻找(尽管有各种快捷的方法罗列出方法列表),相比还是前者更容易些。

最后一点,如果项目组就我一个开发人员,那么还有必要“一个接口对应一个实现类”么?我建议还是遵守这样的规范吧,毕竟养成良好的习惯,你不可能一辈子都做“只有一个开发人员的项目”。

说了一大圈,最后好像绕回来了,虽然我们的代码可能没有多实现的场景,甚至项目的开发人员只有你一个人,但还是建议大家面向接口编程。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

在 Java Web 项目中,Service 层和 Dao 层真的有必要每个类都加上接口吗相关推荐

  1. Service 层和 Dao 层有必要为每个类都加上接口吗?

    以下文章来源方志朋的博客,回复"666"获面试宝典  作者:架构思维 toutiao.com/i6882356844245975563 前几天刷头条又刷到了「Service层和Da ...

  2. 实战:在Java Web项目中使用HBase

    在此之前我们使用MySQL作为数据源,但发现这数据增长速度太快,并且由于种种原因,因此必须使用HBase,所以我们要把Mysql表里面的数据迁移到HBase中,在这里我就不讲解.不争论为什么要使用HB ...

  3. JAVA Web项目中所出现错误及解决方式合集(不断更新中)

    JAVA Web项目中所出现错误及解决方式合集 前言 一.几个或许会用到的软件下载官网 二.Eclipse的[preferences]下没有[sever]选项 三.Tomcat的安装路径找不到 四.T ...

  4. 在java web项目中编写自己的代码生成器

    在java web项目中编写自己的代码生成器 转载于:https://www.cnblogs.com/punisher/p/5909943.html

  5. Java / Web项目中的NPM模块Browser-Sync

    Browser-Sync是一个方便的基于Node.js的NPM模块,可用于更快的Web开发. 浏览器同步可在许多设备之间同步文件更改和交互. 最重要的功能是实时重新加载. 我们也可以在Java / W ...

  6. java web项目中的根路径踩坑

    以下总结来自于颜群老师课堂笔记. java web项目中的"/"怎样区分? 项目根目录: WebContent \ src(所有的构建目录) 如果WebContent中有一个文件i ...

  7. Java Web项目中缺少Java EE 6 Libraries怎么添加

    Java Web项目中缺少Java EE 6 Libraries怎么添加 具体步骤如下: 1.项目名称上点击鼠标右键,选择"Build Path-->Configure Build P ...

  8. Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob.Apache POI.Java2Word.iText等各种方式,其实在从Office 2003开始,就 ...

  9. 在java web项目中实现随项目启动的额外操作

    前言 在web项目中经常会遇到在项目启动初始,会要求做一些逻辑的实现,比如实现一个消息推送服务,实现不同类型数据同步的回调操作初始化,或则通知其他客户服务器本项目即将启动,等等.对于这种要求,目前个人 ...

最新文章

  1. DOS下读取4GB内存
  2. 智能角阀中的电子芯片_电子科技大学胡维昊教授:人工智能在可再生能源系统中的应用...
  3. 安装了git之后visual studio 2019变得很卡怎么办?(工具 --> 选项 --> 源代码管理工具【设置成无】)
  4. 集宁师范学院泉山校区计算机系,集宁师范学院有几个校区及校区地址
  5. JS的常用正则表达式 验证密码
  6. 利用spring注解创建bean
  7. 7-9 根据后序和中序遍历输出先序遍历 (10 分)
  8. JAVA实现二叉树带权路径长度和_哈夫曼树的构建与最小带权路径长度
  9. 入门笔记 Day two
  10. 三相PWM整流器dq解耦控制
  11. Ubuntu14.04/16.04安装Dukto
  12. 悬赏任务源码系统带app小程序源码基于php开源版
  13. 全新天狼星网络验证系统源码+功能强大
  14. 从数据备份恢复来看,iCloud和iTunes到底有什么区别?
  15. 数据分析之Excel
  16. java aspose 加水印_使用Aspose.words for java去掉Word文档的水印(底图)
  17. 【keras学习(三)】mnist手写图片分类程序(一)
  18. [硬件]导热垫(Thermal Pad)和导热过孔(Via for thermal pad)
  19. C# 构造器-实例构造器,类型构造器
  20. html如何添加音乐火狐,电脑如何将HTML书签导入进火狐浏览器中

热门文章

  1. java for stl_STL迭代器
  2. java错误代码1061_java.sql.SQLException
  3. mysql报错代码10051_socket error 10061/11004/10053/10051等错误总结
  4. 对delegate进行扩展 打造通用的计时完成方法
  5. 搜索插入位置的golang实现
  6. linux下安装python3
  7. 大数据-平台-解决方案-基础架构一览
  8. .NetCore~框架版本号不同引起dotnet不能run它
  9. 《Kotlin项目实战开发》第1章 Kotlin是什么
  10. 《Ember.js实战》——2.3 计算属性