IOC 本质是为了实现 AOP
我有点吃惊, 没想到 Java 界的大佬对这两个概念有和我完全不一致的认识. 所以写下这篇博客, 并借此机会重新学习一下 IoC 和 AOP, 确保自己对这两个后端开发非常重要的概念不会有太过偏差的理解
1. IoC
维基文中对此有详细的阐述, 大家可以自行前往维基百科 Inversion_of_control
词条查看, 我就不一一 Copy/Paste 了. 这里帮大家检出几个关键地方捋一捋:
- IoC 是编程原则 - 不是特定的产品, 不是具体实现方式, 当然也和具体编程语言无关
- 在传统编程范式中, 程序调用可重用的库
- 在 IoC 原则下, 程序接受通用框架的调用控制 - 框架调用程序代码
- 与 IoC 原则相关的概念包括:
- IoC 的设计目的包括:
- 将执行任务和任务实现解耦
- 让模块专注于设计任务
- 模块仅依赖于设计契约而无需关注其他系统如何工作
- 避免模块替换时的副作用
到这里我们可以比较清楚地得出下面的结论了:
J1. IoC 的本质不是为了实现 AOP.
那为什么波总会说 "IOC 本质是为了实现 AOP" 呢? 我姑且胡乱猜测一下, 波总想说的有可能是 "DI 本质是为了实现 AOP". 下面我们来探讨一下 DI, 这个和 IoC 以及 AOP 都有关系的概念.
2. DI
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object.
特别地, 维基百科中的 DI 词条给出了下面的描述:
Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.
上面在对 DI 的描述中引入了另一个概念: SoC (Separation of Concern), 中文名关注点分离. 这是计算机科学中的一条设计原则, 简单地说就是将计算机程序划分为独立的单元, 每个单元解决一个可分离的关注点. 这个概念和封装 (Encapsulation) 非常接近, 可以说封装是对 SoC 设计原则的一种具体实现. 而 DI 则被描述为在构造和使用对象上实现 SoC 这个设计原则.
从上面的表述我们可以得到第三条结论:
J3. DI 也不是为了实现 AOP
那 DI 或者 IoC 到底和 AOP 有没有关系, 我们先来看看 AOP 的定义
3. AOP
In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns.
这里面有几个关键点:
- AOP 是一个. 听上去有点晦涩, 下面列举几个编程范式的例子可以帮助大家理解这个概念:
- Imperative - 指令式, c, c++, Java
- Declarative - 声明式, SQL, 各种 DSL, 比如 ANTLR 的语法文件
- AOP 的目的是通过分离横切关注点(Separation of cross-cutting concern) 来提高模块性.
这里的 Separation of cross-cutton conern 是不是有点耳熟? 回顾上面提到的 DI 描述中引入的 Separation of Concern, 两个概念字面相近, 但又不完全一致. AOP 关注的是切面, 而 DI 关注的是对象构造. 如果没有注意到这个异同处, 有可能将 DI (甚至 IoC) 和 AOP 的概念搅和到一起.
扩展讨论
无独有偶, 前段时间 drinkjava (@yong9981) 同学也和我就 AOP 以及 DI 的关系进行了比较深入的探讨, 话题包括:
- AOP 的实现是否必须有 DI 提供
- Web 框架是否必须提供通用 AOP 的实现
- 声明式事务是否必须采用 AOP 来提供
作者:罗格林
出处:开源中国