0

why javaer 什么都要搞一个 interface?

 2 years ago
source link: https://www.v2ex.com/t/855458
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  程序员

why javaer 什么都要搞一个 interface?

  asanelder · 2 小时 14 分钟前 · 1464 次点击

最近看了几个 web 项目, 不明白的是, 为什么到处都是 interface? 而且很多 interface 只有一种实现?

俺理解的是, 只有在抽象的情况下, 以及可能有多种实现的情况下, 才需要 interface, 比如一个

IUserRepo 表示用户数据的存储, 而存储方式可能是有多种情况, 为了不在业务层耦合到具体的存储方式, 所以使用接口没问题.

但像以下这种

IUserService

UserSeriveImpl

对于这种业务层为什么还要抽象一种接口? 俺好像没见过 IUserService 这种接口有多种实现的情况?

48 条回复    2022-05-26 17:34:36 +08:00
janus77

janus77      2 小时 12 分钟前

面向接口编程是这样的
dcalsky

dcalsky      2 小时 10 分钟前

如果经常写测试你就会发现除了正常的实现,还有一种叫 mock 实现。

结论:写 interface 是方便测试的时候 mock 以及今后多实现拓展;但是现实却是很多人压根不写测试,活生生把 interface 玩成样板模板。
eote

eote      2 小时 10 分钟前

使用 interface 进行 AOP 效率比较高,因为对外暴露的方法已经确定了。还有就是 web 领域外包遗毒,DDD 模式深入骨髓
Oktfolio

Oktfolio      2 小时 5 分钟前

Spring 在 AOP 的时候,类实现了接口就使用 JDK 动态代理,没有则使用 CGLib
zzzkkk

zzzkkk      2 小时 5 分钟前

那种设计已经成了业界标准
更恶心的是
有人竟然把这套东西搬到 php

这套东西最没技术含量
unco020511

unco020511      1 小时 56 分钟前

因为这是毒瘤模板
pavelpiero

pavelpiero      1 小时 56 分钟前 via Android

pavelpiero

pavelpiero      1 小时 54 分钟前 via Android

你好,其实你举例的 userservice 最贴近这种场景了,因为多样化的登录方式会涉及到不同的实现,比如密码登录,扫码登录,刷系统授权登录。
banmuyutian

banmuyutian      1 小时 50 分钟前

因为大部分是毒瘤模板+1
crysislinux

crysislinux      1 小时 47 分钟前 via Android

这就叫依赖反转
asanelder

asanelder      1 小时 45 分钟前

@dcalsky #2 应该是 mock 的 repo 吧, 比如, 测试的时候, 可能不依赖真实的数据库, 而是依赖内存存储之类的, 本来就是要测试业务逻辑的, 不应该 mock UserService 这咱吧...
@Oktfolio #4 第二种不是效率更好么?
@zzzkkk #5 一直没找到这种标准是从哪里来的... 找不到出处啊, 铁子
@pavelpiero #8 俺理解的是, 如果登陆方式要抽象的话, 设计一个 ILogin 接口就好, UserService 依赖这个, 而不必把 UserService 也搞成接口
JaguarJack

JaguarJack      1 小时 44 分钟前

明明业务里面只有一种实现,为什么还需要定义 Interface ?我也有这样的疑问
yohole

yohole      1 小时 40 分钟前

对于大型项目或者可预见会持续迭代的中大型需求,面对接口编程没有错,成本也是基本客户忽略

但是实际情况下正如你所说的,很多系统或者需求可能在第一次上线之后,基本很少改动或者不会有变化了,这种情况下完全可以直接写实现的,不需要任何接口的实现

如果一定要扯远一点,这有可能是因为 JAVA 从诞生的那一刻的定位和宣传都是企业级,可维护性和可扩展性可能是要放首位的

然后很多后来者不断受着各种设计模式和大量开源项目的影响,于是就慢慢变成现在的"标准"和事实了
Oktfolio

Oktfolio      1 小时 39 分钟前

@asanelder JDK 动态代理从 1.8 开始就比 cglib 高了吧。不过大多数人不会考虑这个问题,按照“传统”来就是了
makelove

makelove      1 小时 38 分钟前

@zzzkkk php 作者绝对是个脑残 java 粉,连语法都抄 java,甚至以前半官方的 Zend 框架都一股子恶臭 Java 味。
LeegoYih

LeegoYih      1 小时 35 分钟前

有没有一种可能,人家用 interface 是为了 RPC 准备的
offswitch

offswitch      1 小时 32 分钟前

你的理解是对的,很多人不懂,就喜欢这样呗,没办法。
wolfie

wolfie      1 小时 30 分钟前

面向 kpi 设计带来的习惯,只有一个实现不需要这么做。
系统性搞过架构的毕竟少数。
statumer

statumer      1 小时 29 分钟前 via iPhone   ❤️ 1

这种做法对于项目管理是有好处的,不要觉得用接口就是为了替换实现。
如果搞个 Interface ,开发者就只能暴露方法,不会乱暴露对象成员变量,减少 caller 做 hack 的可能性。
elintwenty

elintwenty      1 小时 27 分钟前

某些情况比如 rpc 需要 interface 、或低版本的一些实现方式,而且 interface 就算只有一个实现类的情况,可以起到 中高级开放人员编写 interface 交给其他人开发 的管理作用,或者更方便的看提供接口,直接看实现类代码量较大(虽然这个可以被插件或 ide 取代)
BBCCBB

BBCCBB      1 小时 27 分钟前

为什么我在只有一个实现的时候就不搞?
mgcnrx11

mgcnrx11      1 小时 27 分钟前

经历过麻木写 Interface ,然后变成觉得都是一种了就不写 Interface ,到最后维护的项目需求确实增长超出预期又退回去老老实实写 Interface 的阶段

这种设计模式嘛,你不知道后面会不会有用得上的时候,当真的用得上多种实现,就会庆幸当年没有偷懒写一个 Interface 了
MicroGalaxy

MicroGalaxy      1 小时 23 分钟前

模板吧,我见过项目绝大部分都是只有一个实现。况且我写自己项目的时候都不写 Interface ,真的用不上
Bingchunmoli

Bingchunmoli      1 小时 20 分钟前 via Android

代码生成的,也方便后续自己写其他实现..
Bingchunmoli

Bingchunmoli      1 小时 16 分钟前

1. Spring 在 AOP 的时候,类实现了接口就使用 JDK 动态代理,没有则使用 CGLib
2. service 不写接口 有可能被 leader review 的时候打回来
3. 代码生成无成本
dcalsky

dcalsky      1 小时 11 分钟前

@asanelder Service 也可能 mock 呀,只要被依赖了,就应该被 mock 。
zzzkkk

zzzkkk      1 小时 7 分钟前

@asanelder
一直没找到这种标准是从哪里来的... 找不到出处啊, 铁子
===================
出处肯定可以追朔到 j2ee 早期 从 interface 这东西诞生以后
lengyuqu

lengyuqu      1 小时 5 分钟前

因为这样的模板开发过程中不容易出错,而且可以大量使用码农投入开发。

任何大规模普及的开发模式一定不是出于技术角度,而是商业运行的角度。显然这个更符合商业运作
lanlanye

lanlanye      1 小时 1 分钟前

现实确实是大部分接口只有一种实现,但对外使用接口能让你在更改实现的时候更好做一些,另外就是上面提到的需要 mock 的场景,这个可能更常见。

在 Golang 里还有避免写 * 这个理由……
ComputerIdiot

ComputerIdiot      1 小时 0 分钟前 via Android

有人用 interface 做 mixin 吗?
nicevar

nicevar      1 小时 0 分钟前

再怎么吐槽,这都是 Java 一个非常好的地方,就是再烂历史包袱再重的项目随便换个人来接手,还能干得下去,换成其他语言实现的,都不想瞧一眼。
cubecube

cubecube      59 分钟前

框架用 interface 无可厚非,业务代码实现 interface 不香么
Huelse

Huelse      55 分钟前

留下足够丰富的信息确保项目可以持续迭代,哪怕是 shi
chendy

chendy      53 分钟前

repo 用接口,方便多实现 / mock
往上的其实直接 class 就行了
spring 很早就自带 cglib ,没接口不能出代理的时代已经过去了……
cheneydog

cheneydog      49 分钟前

我觉得 java 的 Interface 挺好的,语法上也没强制要写呀,只是习惯上要写,我也写,默认实现怎么快怎么来,期待着未来能改进。

我也希望 nodejs 中能写 interface ,但是不想用 ts 。
darksword21

darksword21      43 分钟前 via iPhone

如果突然某一层要换的话确实很方便,比如数据库,上层基本不用变,当然在公司里一般写完也不会变了

我是说我在 go 中这么写,java 没经历过
guxingke

guxingke      42 分钟前

如无必要 勿增实体

---
不妨从自己做起,没必要声明的时候就不声明呗。
毕竟真有必要的时候,再抽出一个接口并不困难。
Kaiv2

Kaiv2      39 分钟前

说下这种模式的优点
IUserService

UserSeriveImpl

我开发一个依赖 UserService 的模块, 你负责 UserService 模块的开发,但是还没实现。你可以先提供接口给我。

类似的 ( dubbo 服务也是这样)
slimhigh

slimhigh      32 分钟前

你的理解是对的。大部分情况下是没什么用的,大家生搬硬套罢了。
retrocode

retrocode      30 分钟前

规范嘛, 恶心是真滴恶心, 不过好处是有这么一套通用甚至垄断的规范在, 不至于太恶心,不然高情商点百花齐放,低情商则神魔乱舞,一个人一套规范,天天吵最佳实现谁也不服谁那才是真的恶心了
ThinkCat

ThinkCat      27 分钟前

如果不涉及到多实现,那可以不用 interface ,直接写 class 实现就行了。但是如果明确在后期存在扩展的情况,一定要定为接口,避免后期大范围的修改代码
potatowish

potatowish      22 分钟前 via iPhone

有规范就容易产生模板式的代码,但是没有规范,大家各写各的,不利于团队开发
forbreak

forbreak      19 分钟前

大部分情况下没用,但是一旦要用,你之前写了跟没写 差距久出来了。 我只一个旧项目,改 rpc 调用,之前写了 inteface 很容易久迁移好了。没写的话,就得重新写一遍。。
FreshOldMan

FreshOldMan      15 分钟前

不容易出错
FreshOldMan

FreshOldMan      14 分钟前

相当于注释了吧
panpanpan

panpanpan      13 分钟前

虽然 Spring 在 AOP 的时候,类实现了接口就使用 JDK 动态代理,没有则使用 CGLib
但是实际上大家都用 springboot, springboot2.0 之后默认情况下不管你有没有接口统统用 CGLib
yazinnnn

yazinnnn      5 分钟前

写 spring 不会写,都是单实现,基本不会写接口

写 vertx 时会, 因为会用到 service proxy 和 codegen

基于 future 的接口 client, 会把 reactive 的 client 给你包好
基于 future 的接口服务, 会把 eventbus proxy 生成好


现在改用 quarkus,然后又不写接口了....
lixiaohui0812

lixiaohui0812      1 分钟前

test + 多个实现

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK