download:Spring Security + OAuth2 精讲 多场景打造企业级认证与受权
明天咱们要探讨的问题是:Service 层需要接口?
现在拆散我参加的我的项目以及浏览的一些我的项目源码来看。如果「我的项目中使用了像 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