IOC? IOC与DI?

✅ 那什么才算 IoC?我们重申一次标准:

真正的控制反转需要满足这三个条件:

条件是否满足解释
你不创建依赖对象Kitchen.createFood() or agent.getVehicle() 是“工厂”,你没直接 new
你不注入依赖对象你手动调用 setFood()setVehicle(),控制权仍在你手中
容器/外部框架控制依赖注入流程没有任何容器帮你自动注入

✅ 所以更准确地说:

示例是否 IoC?是否有 IoC 的“倾向/味道”?
Kitchen.createFood() + setFood()❌ 不是✅ 有工厂感
agent.getVehicle() + setVehicle()❌ 不是✅ 有 service locator 的风格
Spring.getBean(Food.class) 然后自动注入✅ 是✅ 真正的 IoC

🧠 一句话解释区别:

IoC 是思想(理念),DI 是具体实现方式之一。

🔍 来拆解下这两个词:

✅ IoC(Inversion of Control)控制反转:

  • 是一种 设计思想
  • 目标是:把控制权从程序员手里“反转”给框架或容器
  • 不再由你手动控制程序流程和对象组合,而是由框架来“自动调度”

比如:

你不自己 new,不自己调用 set,框架帮你搞定一切

✅ DI(Dependency Injection)依赖注入:

  • 是一种 实现 IoC 的具体技术手段
  • 它的核心是:将依赖通过某种方式“注入”给目标对象
  • 有 3 种常见形式:
    • 构造器注入
    • Setter 注入
    • 接口注入

✅ 关系总结图:

            +--------------------+
            |   Inversion of     |
            |    Control (IoC)   |  <== 一种思想、原则
            +--------------------+
                       |
      +----------------+------------------+
      |                                   |
+-------------+                +--------------------+
| Dependency  |                |  Service Locator   |
|  Injection  |                | (另一种实现方式) |
+-------------+                +--------------------+
     |
+---------------------------+
| 构造器注入、Setter注入等 |
+---------------------------+

✅ 再简洁一点:

对比项IoCDI
是什么一种设计思想一种实现方式
控制谁控制“对象如何创建和依赖如何组合”的权力从你手中“反转”出去指定“依赖应该怎么注入进来”
关系包含关系:DI 是 IoC 的一种实现手段属于 IoC 的一种实践方式
举例Spring 框架控制 Bean 生命周期@Autowired 注入依赖

✅ 什么是 Service Locator?

Service Locator 是一种 设计模式,其核心目的是:

提供一个全局的服务查找器,通过它你可以在任何地方查找、获取到需要的服务或依赖对象,而不需要手动创建和管理。

换句话说,它是一个中介,负责管理对象的创建和查找。你只需要请求它来获取服务,而不用关心服务怎么创建或者存在哪儿。

🧠 核心思想:

从服务定位器(Service Locator)中获取服务,而不是自己直接管理和创建对象。

🚨 但是,这种方式的问题:

虽然 Service Locator 提供了“获取依赖”的能力,但它有一个隐含的缺点:
它破坏了“依赖显式化”的原则,也就是,你没有直接看出对象的依赖是什么,导致了代码的可维护性差,特别是当系统变得复杂时。

这和 DI 的区别:

  • DI 明确地告诉你:你需要哪些依赖,并且这些依赖会通过某种方式(构造器、setter 等)注入给你。
  • Service Locator 则是通过一个全局对象来管理和查找依赖,你在使用时不关心这些依赖怎么被创建的。

✅ 举个简单的例子:

1️⃣ 没有 Service Locator(直接依赖注入):

public class Restaurant {
    private final Food food;

    public Restaurant(Food food) {
        this.food = food;
    }

    public void order() {
        food.eat();
    }
}

通过构造器注入 Food,明确表达了 Restaurant 依赖于 Food。当你创建 Restaurant 时,需要显式地提供 Food

2️⃣ 使用 Service Locator:

public class Restaurant {
    private Food food;

    public void order() {
        // 通过 Service Locator 获取 food
        food = ServiceLocator.getService(Food.class);  
        food.eat();
    }
}

在这个例子里,Restaurant 并不直接关心 Food 是怎么被创建的,它只是通过 ServiceLocator.getService(Food.class) 去查询获取 Food
你不用显式地提供 Food,而是让 Service Locator 去处理。

Service Locator 类的简单实现:

public class ServiceLocator {
    private static Map<Class<?>, Object> services = new HashMap<>();

    // 注册服务
    public static <T> void registerService(Class<T> serviceClass, T serviceInstance) {
        services.put(serviceClass, serviceInstance);
    }

    // 获取服务
    public static <T> T getService(Class<T> serviceClass) {
        return (T) services.get(serviceClass);
    }
}

在这段代码中,ServiceLocator 提供了一个静态方法来获取所有注册过的服务对象,而你不需要关心这些对象是怎么创建的。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇