V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX  ›  程序员

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

  •  
  •   edis0n0 · 2023-03-07 22:56:28 +08:00 · 2135 次点击
    这是一个创建于 625 天前的主题,其中的信息可能已经有所发展或是发生改变。
    18 条回复    2023-03-10 10:50:04 +08:00
    arloor
        1
    arloor  
       2023-03-07 23:03:01 +08:00
    依赖接口而不是实现,面向对象的基础都没有打牢吗
    Saxton
        2
    Saxton  
       2023-03-07 23:05:50 +08:00
    1.解耦
    2.提高代码可用性

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

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

    假设用的实现类注入,不需要注入 B 类了就删掉注入 B 的代码,直接注入 C 类可以吗?
    假设用的接口注入,我理解接口也是要写 `@Qualifier` ,且对上述并不能体现其解耦性。
    CodingNaux
        15
    CodingNaux  
       2023-03-08 17:25:23 +08:00
    为什么你会有这个问题....
    有本书可以看看<Dependency Injection Principles, Practices, and Patterns>
    lry
        16
    lry  
       2023-03-08 18:33:01 +08:00
    没啥用,大部分 service 都只有一个实现,写接口反而搞复杂了
    xinshoushanglu
        17
    xinshoushanglu  
       2023-03-08 19:15:02 +08:00
    其实吧,如果一个 interface 只有一个 implement ,那这时候你用哪种注入方式都行。
    mezi04
        18
    mezi04  
       2023-03-10 10:50:04 +08:00
    @notfornothing #14 实际编码应该不会有人说放的好好的实现哪一天突然换了,但你肯定用过 spring 的 @transactional 注解,有没想过它的底层是怎么实现的?或者说是 mybatis 的 mapper 接口类,它又是怎么实现的?这些才是依赖注入真正的用法。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3057 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 00:37 · PVG 08:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.