IoC(Inversion of Control), 意为 "控制反转", 也叫依赖注入 (Dependency Injection), 也有人认为依赖注入是控制反转的一种方式. IoC 的本质是引入代理者以减少依赖关系. 下面通过引入实例以比较 IoC 的好处
假设存在一个普通的业务场景, 获取服务提供者发送的消息并加以处理
以下是上功能实现的类文件
- ```
- public class OurInfoProvider
- {
- private IOurInfoListener infoListener;
- private IOurPersister infoPersister;
- public void getAndPersisterInfo()
- {
- }
- }
- ```
依赖类需要初始化, 这是最直接的处理方式, 我们主动的创建相关类实例, 在 OurInfoProvider 类中形成了对 aInfoListener,aInfoPersister 的直接依赖
- ```
- public OurInfoProvider
- {
- infoListener = new AInfoListener();
- infoPersister = new AInfoPersister();
- }
- ```
但是对于 OurInfoProvider 的业务处理过程, 其并不关心依赖对象的实例化过程, 只需要订阅或引入它们的实例即可, 相关的实例化过程并不应该由 OurInfoProvider 来实现, 对于 OurInfoProvider 而言, 这不是它的职责范围内
基于以上共识, OurInfoProvider 只需要引入依赖对象的实例. 而依赖对象的实例化过程无法忽略, 由其他对象负责; 同时 OurInfoProvider 的引用依赖对象需要来自于一个容器, 这就是 IoC
依赖注入的方式, 构造方法注入, setter 方法注入, 接口注入, 其中接口注入的方式由于侵入性已较少使用; 构造方法注入, 对象初始化后即可使用, 但是构造方法无法被继承, 无法设置默认值; 而 setter 方法注入的特点与构造方法相对
构造方法注入:
- ```
- public OurInfoProvider(IOurInfoListener infoListener, IOurInfoPersister infoPersister)
- {
- this.infoListener = infoListener;
- this.infoPersister = infoPersister;
- }
- ```
常常会看到 IoC 的好处是解耦, 但是却不理解这在实际上到底由什么好, 下面举例说明
假如增加一个 BInfo 的信息源以提供 OurInfoProvider 处理, 当我们以直接创建依赖对象时, 在 OurInfoProvider 内确定了接口的实现对象, 不能复用以满足 BInfo 的对象. 但是假如我们以构造方法注入, 构造方法参数确定接口的实现对象即可. 本质上是对初始化的控制权的转移, 使得 OurInfoProvider 不负责可变之处, 保持通用性即可
- ```
- OurInfoProvider aOurInfoProvider = new OurInfoProvider(new AInfoListener(), new AInfoPersister());
- OurInfoProvider bOurInfoProvider = new OurInfoProvider(new BInfoListener(), new BInfoPersister());
- ```
通过构造方法注入使得 OurInfoProvider 不必修改构造方法
IoC 使得 OurInfoProvider 不关心引入依赖对象的初始化过程, 也就是其初始化过程对 OurInfoProvider 是非侵入式, 分离的, 可以添加钩子等各种处理过程, 而 OurInfoProvider 无感知. 例如对引入依赖对象的 Mock, 但不影响 OurInfoProvider 的任何逻辑, 而这也正符合 IoC 的意义
来源: http://www.bubuko.com/infodetail-3098521.html