Spring 里 Service 层分成接口+Impl 的好处是什么?

2021-01-02 18:17:37 +08:00
 AAASUKA

分开写感觉很累赘,为什么很多人这么选择?
为什么不直接用一个 Service 类实现

8427 次点击
所在节点    Java
70 条回复
Hadoop270
2021-01-03 14:39:14 +08:00
这个问题 在我刚学 java 的时候也想到了- -
xiangyuecn
2021-01-03 14:49:06 +08:00
以前也写过 XXXService XXXImpl,还有 XXXMapper.java XXXMapper.xml , 还有 XXXEntity 还有 XXXController

繁琐,堆砌,复用说不上,难看才是真的

现在只剩 XXXController,其他的除非确实必要,否则一概不写😂
zhazi
2021-01-03 15:14:07 +08:00
粘一段 Jhispter 对这里的理解
zhazi
2021-01-03 15:15:39 +08:00
Should we use interfaces with our Service Beans?

Short answer: No.

If you want the long answer, here it is:

One of the main interests of using Spring is AOP. This is the technology that allows Spring to add new behaviors on top of your Beans: for instance, this is how transactions or security work.

In order to add those behaviors, Spring needs to create a proxy on your class, and there are two ways of creating a proxy:

If your class uses an interface, Spring will use a standard mechanism provided by Java to create a dynamic proxy.

If your class doesn’t use an interface, Spring will use CGLIB to generate a new class on the fly: this is not a standard Java mechanism, but it works as well as the standard mechanism.

Some people will also argue that interfaces are better for writing tests, but we believe we shouldn’t modify our production code for tests, and that all the new mocking frameworks (like EasyMock) allow you to create very good unit tests without any interfaces.

So, in the end, we find that interfaces for your Service beans are mostly useless, and that’s why we don’t recommend them (but we leave you with the option to generate them!).
loongwang
2021-01-03 15:16:01 +08:00
降低其他人的阅读难度, 例如你这个 service 代码很多,有很多 private 方法, 当其他人用到或者阅读你的代码时, 可以直接从接口中获取到必要的信息,而不是去读一遍你的代码才能获得必要的知识,
asanelder
2021-01-03 16:59:24 +08:00
@hantsy #21 "猴急" 这个词用的真实。。。

"如果做国外的产品项目就完全不一样,你有很多机会去想如何才能做到真正的逻辑上的解耦。”

国外真的这样么?

@hantsy #27 俺遇到的基本都是:设计和测试是最不给时间的,每天都是写写写,然后早会汇报完成了多少多少。

你要是连着几天汇报在搞设计,上面会认为你在没有任何产出。。。

有时真不知道这些“上面”当初是如何写软件的。难道他们也不是过来人么?难道他们体会不到这东西也要设计,也要 demo 的么。。。
asanelder
2021-01-03 17:06:03 +08:00
俺感觉楼主面对的项目是这样子的。

1. 贫血模型:从 dao 层查出来的只是数据,而且是和具体 dao 层字段绑定的格式(如 mysql )
2. 所有的业务都在 service 层( service 中各种对贫血模型字段的判断和处理)

因为"业务"本身就不是抽象的,不需要多实现,所以,导致的就是 service 接口和对应一个 service impl 这种鸡肋的形式存在。你想想,同一 service 接口,你还能有其它什么实现么?

真正需要接口的是需要抽象时,需要和具体实现无关时,如

一个接口 UserRepository 表示用户数据仓库

而实现可以是

FileUserRepository
DBUserRepository
XXXUserRepository

这样多实现是有意义的。

而业务都写在 service 类里,那么业务的多实现指的又是什么呢?

造成楼主的困惑原因,可能就是"前人都这样写,那我也这样写吧"

于是,就这样了
qiumaoyuan
2021-01-03 17:10:09 +08:00
高级
fkdog
2021-01-03 17:39:40 +08:00
我觉得我们应该用发展的眼光看问题.
service-impl 以及设计模式不是啥圣经, 大部分项目开发搞这些玩意纯属没事找事.
liuxey
2021-01-03 19:38:27 +08:00
我的个人见解:就是历史糟粕
xcstream
2021-01-03 20:06:14 +08:00
可以按代码量算 kpi
NilXuan
2021-01-03 20:38:40 +08:00
从数量上来看,一个 Service 可以对应一个多个 Impl ;面向接口编程可以使多个 Impl 之间的替换变得极为简单;比如,开发时,我把验证码发送到控制台;上线后切换到真实运营商服务,只需改变注入的 Bean,而无需到处修改;这就是好处(之一);
需要考虑的问题是,是用不到还是没有用?如果用不到,是设计没设计好,还是根本没设计?是本来就用不到,还是应该用到,但是没有用到?我认为不能简单地说有用还是没用;个人不认同“历史糟粕”或者“历史遗留”这种看法;至少这种一对多的关系,就是比一对一要灵活;
kkeep
2021-01-03 20:56:40 +08:00
对我来说只有一个好处,就是强迫自己设计接口。而不是 impl 里面随意加函数。
joecqupt
2021-01-04 00:24:42 +08:00
接口可以用 JDK 做动态代理,方便之后暴露 RPC 或者其他什么逻辑处理
Aresxue
2021-01-04 10:35:17 +08:00
老月经贴了,继承->接口实现->容器->注解,当你能清晰弄清楚它们的依赖程度并能在项目中选择合适的时候你就不会有困惑了。当然这是对于需要精细打磨的项目而言,而大多数的项目本身就是对业务,本身就是一种快消品罢了
reed2020
2021-01-04 11:50:41 +08:00
我接触到的一些这样写的项目,它们的 service 和 impl 都是一一对应的,没啥卵用。
Zhancha
2021-01-04 13:30:53 +08:00
项目经历应该会很爽,直接看就行,不需要看里面的。
jk1030
2021-01-04 13:37:33 +08:00
面向接口,重构的时候及其舒爽
另外还有一个就是代理呵 rpc 吧
jason19659
2021-01-04 13:59:18 +08:00
@loongwang #36 但是现在所有 ide 都有 schema 啊
hyqCrystal
2021-01-04 14:21:13 +08:00
@joecqupt 但实际上即便是暴露给 RPC 大多数是 API 层暴露给 RPC

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/741075

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX