为什么依赖注入用的是 Interface 不是 Class?

2023-03-07 22:56:28 +08:00
 edis0n0
1947 次点击
所在节点    程序员
18 条回复
arloor
2023-03-07 23:03:01 +08:00
依赖接口而不是实现,面向对象的基础都没有打牢吗
Saxton
2023-03-07 23:05:50 +08:00
1.解耦
2.提高代码可用性

打个比方,如果 A 类依赖 B 类, 此时我们不需要 B 类了,只需在 B 类实现的接口上在定义一个 C 类,然后把 B 类不加入容器,C 类加入容器,此时你的代码逻辑走的就是 C 类的逻辑了
另外可以利用这个特性来取容器中所有属于这个接口实现的对象的集合
Saxton
2023-03-07 23:06:58 +08:00
例如,如果我们有一个 OrderService 类,它依赖于一个 PaymentService 类,如果我们在 OrderService 中直接使用 PaymentService 的实例,就会导致 OrderService 与 PaymentService 的紧密耦合,后续修改将变得困难。

因此,我们就可以通过使用接口(Interface)而不是类(Class)来解决这个问题。具体做法是,我们定义 PaymentService 接口,然后在 OrderService 中声明一个 PaymentService 类型的成员变量,并使用接口类型实现依赖注入。这样,当我们需要更改 PaymentService 实现时,只需要修改这个实现,而不需要对 OrderService 进行修改。
Saxton
2023-03-07 23:09:18 +08:00
第二场景:
策略模式, 使用依赖注入可以轻松完成, 只需定义一个接口类型的泛型 list ,spring 会自动注入该接口所有实现类并加入的容器的对象
securityCoding
2023-03-07 23:24:03 +08:00
写过 mock 没,去试试
huijiewei
2023-03-07 23:26:20 +08:00
interface 是依赖
class 是注入
jorneyr
2023-03-08 09:03:03 +08:00
接口和类都可以的,实验一下就明白了。
hhjswf
2023-03-08 09:06:45 +08:00
@Saxton 解藕效果一般吧,直接 new 一个是不是也能起到类似效果?容器作用我认为是避免创建销毁对象的开销?
hhjswf
2023-03-08 09:16:05 +08:00
@jorneyr 对呀,我差点怀疑人生了,以前💩山项目都不写接口实现类照样注入
7911364440
2023-03-08 09:29:47 +08:00
@hhjswf 你猜它为什么变成💩山了呢
Aresxue
2023-03-08 10:36:47 +08:00
当然可以用 class 只是 interface 的耦合更低,一般优先推荐 interface ,内部服务能确定不需要给别的服务复用的注入 class 也没啥问题。
ljsh093
2023-03-08 11:23:41 +08:00
补充一个可以解决循环引用
aw2350
2023-03-08 11:42:34 +08:00
面向对象的基准大家都不遵守,只图自己省事。
notfornothing
2023-03-08 15:25:00 +08:00
@Saxton 同楼主疑惑,我没能理解耦性

假设用的实现类注入,不需要注入 B 类了就删掉注入 B 的代码,直接注入 C 类可以吗?
假设用的接口注入,我理解接口也是要写 `@Qualifier` ,且对上述并不能体现其解耦性。
CodingNaux
2023-03-08 17:25:23 +08:00
为什么你会有这个问题....
有本书可以看看<Dependency Injection Principles, Practices, and Patterns>
lry
2023-03-08 18:33:01 +08:00
没啥用,大部分 service 都只有一个实现,写接口反而搞复杂了
xinshoushanglu
2023-03-08 19:15:02 +08:00
其实吧,如果一个 interface 只有一个 implement ,那这时候你用哪种注入方式都行。
mezi04
2023-03-10 10:50:04 +08:00
@notfornothing #14 实际编码应该不会有人说放的好好的实现哪一天突然换了,但你肯定用过 spring 的 @transactional 注解,有没想过它的底层是怎么实现的?或者说是 mybatis 的 mapper 接口类,它又是怎么实现的?这些才是依赖注入真正的用法。

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

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

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

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

© 2021 V2EX