以前我也是遵循各大教程,在 Service 层创建 interface,然后创建 impl 类实现它。教程中一般会说:
- 为了扩展,可以在有需要的时候方便的替换为别的实现,通过 Spring 的依赖注入,不需要修改调用端代码
- 为了让 Spring 使用比 cglib 更高效的动态代理
当我写了很多很多的后端代码,经常会遇到需要在 Service 添加一个方法的时候,需要编辑 interface 再写 impl 代码逻辑,明明这个 interface 实现就只有一个,基本不可能会有另一个 impl 去实现,为了虚无飘渺的高效动态代理真的有必要吗?
再后来,轮到我主持项目的时候,我就再也不写 Service 的 interface 了,然而整个项目上线后,也没出现过什么性能问题。直到后来有需要把项目中权限控制相关功能使用的 shrio 修改为 spring-security 时,验证相关的 Service 需要一个的方法模板来确保顺利切换,才创建了一个 interface 用于在开发阶段统一验证相关的方法分别在 shrio 和 spring-security 中实现。等 spring-security 实现完后,只需要将注入 IoC 的 Service 从 shrio 实现的 impl 切换为 spring-security 实现的 impl 就可以完成切换技术栈。
今天刚好又看到一个视频聊到这个问题,视频中有说到 Mybatis 的一个代码生成插件的作者的代码库中在很久之前有用户提过一个类似的issue,问到代码生成时,是否能提供生成@Service 类的 interface 文件。
看讨论的内容应该是早期这个插件生成的代码只是单一的@Service 文件,不会生成对应的 interface。作者也在下面回复说作者本人在编码的时候基本不写 interface。
在我看来,Service 层的 interface 其实不是必要的,只是有些人写代码时并不怎么思考,只想着完成工作。学习的时候怎么学的,或者项目以前是怎么写的就照搬照抄,没怎么思考过代码结构的意义。感觉在 Java 程序员圈子里总会出现一些很奇怪的”习俗”,比如不管业务合不合适也追随大厂的技术栈,比如一些约定俗成的编码习惯但是不知道为什么,比如现在机器资源并不贵的情况下写个简单的 Java Web 项目却使用各种弯弯绕绕的方式方法为的是”听说这样性能好”。