什么是控制反转(Inversion of Control)

时间:2022-05-16 17:06:20

yqj2065不敢使用控制反转(Inversion of Control、IoC)这个术语了(本来穿衣服是正常的,裸体太流行了,我不敢穿衣服出门。嗯,就是这种赶脚。)

因为流行 控制反转容器=依赖注入容器,然后,太多的烂人省略后面的“容器”两字,得到控制反转=依赖注入;然后,到处是这种错误的信息。我不喜欢这种思维上的蜘蛛网?看看百度百科、360百科或网上搜索“控制反转”,你就懂了,它们说:

“控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,...Spring框架的核心“。

本文最重要的意义,在于告诉你控制反转的来自何处、它的原始含义。



1.什么是反转

一个男人变成女人,叫变性;一个女人明天还是女人,叫...自然。所以,讨论反转,需要你有两次体验

教材上,SortTest针对IntSort编程后,能够方便地复用于对各种IntSort实现算法的测试。

考虑另外一种场景,SortTest中提供了检查与JDK排序算法的一致性(保证排序正确)、大规模测试的时间观察等代码,希望能够复用SortTest。或者说,SortTest和IntSort是老师预先提供的测试工具并打包提供给学生,学生随后编写自己的某种排序算法并被要求复用该包。这种场景,可以称为对排序测试框架的复用

框架/framework是在底层中定义的一个骨架式方案,处理各种应用中面临的共同的底层细节;而应用程序员可以按照自己的需求使用框架,给出自己的功能实现——只需要填入自己的东西。

SortTest是测试流程的控制模块。当应用程序员编写SortTest,他感觉一切都在他的(代码的)控制之下。也就是说,应用程序员决定要干什么、程序的流程是什么、调用Java的各种库函数。当SortTest属于框架,框架控制了程序的流程,而应用程序员仅仅是填空式编程——编写@Override方法。

控制模块SortTest所在层的不同,被形容为控制反转(Inversionof Control,IoC[1]。或者说,控制模块可以作为上层模块,也可以作为下层模块,两者的差别体现了控制的反转。 IoC说明了框架与库的不同,控制反转是框架的特点/特征。


[1]参考Ralph E. Johnson & Brian Foote,DesigningReusable Classes,1988,链接

http://www.laputan.org/drc/drc.html

One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user's application code. 

The framework often plays the role of the main program in coordinating and sequencing application activity.

 This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.

上面的这段话,就是控制反转(Inversion of Control)的来由

所以,你一定要知道 控制反转(Inversion of Control)说的就是框架。如果你清楚地知道库与框架的区别,你不需要控制反转这个术语。

(本来IoC不过是一篇文章中的短语,被某些依赖注入容器自称为控制反转容器后,这个词控制反转IoC成为流行感冒一样的流行词。)


★控制反转是框架的特点/特征

所有框架都具有控制反转的这个特点。说依赖注入(Dependency Injection)就说依赖注入呗,非得自称控制反转容器,难怪Martin Fowler要开骂:几位轻量级容器的作者说..."我的轿车是与众不同的,因为它有四个*"。

更重要的是,如果我们如同使用God类那样使用依赖注入工具,则该依赖注入容器仅仅是一个库/工具,而非框架,因而该依赖注入工具与控制反转无关。

2.不喜欢

框架编程/设计框架时,如Java Applet框架定义各种回调接口如 init()等生命周期方法,应用程序员则给出@Override init()等回调(即回调函数)。因此,yqj2065直接使用回调等术语,不太需要说明框架的特点的IoC。


好多人编写SSH( struts+spring+hibernate)应用程序,如果你觉得写了几年SSH应用程序没有什么成就感的话,你可以写一个Helloworld级别的程序,如:

package tips;
import static tips.Print.*;//替代System.out.println()等
import java.util.Scanner;
/**
 * @author yqj2065
 * @version 0.1
 */
public class InputDemo{
    public static void demo() {
        Scanner scanner = new Scanner(System.in);
        p("请输入姓名: ");
        pfln("Hello! %s!", scanner.next());
        p("请输入年龄: ");
        pfln("OK! %d!", (int)scanner.nextDouble());
        p("是男生吗?(true or false): ");
        pfln("ye! %s!", scanner.nextBoolean()?"男":"女");
    }
}
并且大声地、傲娇地宣布:

我编写了一个控制正转的程序

顺便说一句:如果你真的想问相关问题,请问“什么是控制反转容器?,或者依赖注入容器”!



相关文章