`
zh_harry
  • 浏览: 102454 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
877aca81-daac-33c8-8bf9-3a886cebc6c3
自己动手写java 框架
浏览量:28410
社区版块
存档分类
最新评论

疯子在思考之IOC

    博客分类:
  • JAVA
阅读更多
控制反转 英语:Inversion of control,缩写为IoC
我想很多同学都会思考过这样的一个问题,控制反转,什么地方反转了,是不是翻译的不对?
这里插一句
当年马云借着盖茨的嘴说:“互联网会改变世界。”其实是他自己说的,因为那时侯没有人认识马云,如果我说是翻译错误,大家肯定拍砖说我没理解。
大家对spring都用了很多年,有喜欢看书的同学一定会看到过spring 技术内幕,非常棒的一本书,没看的看过这篇博客之后记得买一本。
细心的同学可能会记得这样一句话

早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。--摘自维基百科
其实他真的翻译的不够友好,所以后来才有了依赖注入(Dependency Injection,简称DI)。其实他们说的是一个意思。


bean的历史及工场模式:
最原始的bean是直接new出来的,后来出来了工场,把所有的bean放到工厂里统一生产,但还是写new,只不过这个new放在一个方法里了。再后来就是依赖注入帮了我们大忙,我们看不见new了。其实spring ioc就是一个大工厂 BeanFactory

有好多同学说过接口有什么用?我不用接口一样写代码,我不用spring一样new.

OOP的三个特性是封闭继承和多态,三个特性,继承和多态就占了两个,学java的人都应该看think in java。里面也强调了代码复用的三个方式是组合,继承和代理。这六点其实非常重要。
think in java引入过一个名词叫做"客户端程序员",其实我们所有应用框架的人都是客户端程序员,那么框架的设计的要想到可扩展性和代码的复用性以及兼容性。想想spring就很容易理解,这些都需要接口。

  有接口就会有多态,有多态就需要修改new后边的代码,如果这些写到代码里,很多的话,重构就会带来问题。这是第一点;其二通过ioc可以实现bean的统一管理,很方便,对bean的依赖关系一目了然,很容易把握全局,利于分析。所以ioc确实是非常有用的,是很棒的思想。


从字面上理解,两个词,一个是依赖一个是注入。
谭浩强说过这样一句话:“程序=算法+数据结构”
所以分析Ioc我们从数据结构入手。它实际上有一个beanDefinition 的定义类,要实现注入首先我们要知道某个bean 的class及这个class的依赖关系,然后通过递归进行实例化并注入。
大家都知道spring的bean有两种形式,singleton及prototype
其实了解这些思想之后我们很容易想到其实就是通过对xml的解释来实生成bean的过程,如果是singleton那么我们直接缓存bean.如果是protoype我们缓存class.
所以归结起来最核心的功能就是对xml的解析及递归调用的算法,感兴趣的同学可以参考我框架中的ioc 包,里边有具体实现。
6
12
分享到:
评论
60 楼 zh_harry 2013-07-25  
IOC的这个事情,我们争论了好久,不管结果如何我想到现在大家肯定明白了,至少自己能够把自己说服,IOC对我们工作是有用的。

我和陆老师的争议也比较多,我总结一下吧。其实陆老师的总结已经很到味了,站在他的角度来讲我是有误导成份。

其实大家都明白我们俩要表达什么?只有他和我都在保持着自己的观点,也不用再争论了。其实有一点确实是一致的,就是透过问题表象看本质。

我们陆老师的分歧就是对这个“本质”的理解不一致。
我的理解陆老师认为从理论上讲,更严谨地说,我这么说IOC是错的,而我却一直不承认.就这一点上我给老陆道谦。

下面阐述一下我的观点:

  我理解的本质并不是谁对谁错的问题,而是问题实际的本质。
陆老师强调过是因为spring太过成功而人们忘记了ioc的本质,而他把直接成依赖注入或者就是spring的beanFactory.

The main control of the program was inverted, moved away from you to the framework.
其实就是这句话,所谓的反转是对象的控制权由依赖他的类反转到了框架(可以理解为spring容器,我不知道这样翻译对不对。)
这个概念我曾经坚持过很多年。直到11年前后我准备实现自己的框架的时侯,准备研究一下spring。看到了 spring技术内幕这本书。我并不没有强究书中引用是对还是错的,而我认为这样理解是最简单的,确实用老陆的话讲,是spring把ioc实现得太简单了。

再回到“本质”上来,我们都是程序猿,做过项目,从jdbc直接写sql到分层,到工厂模式,再到spring ioc容器。
这一路走来肯定有很多迷惑的地方,我们为什么要用spring ioc.他到底给我们带来了什么?给我们的开发和维护带来了哪些好处?我认为这才是我们真正要追究的问题本质。至于ioc到底怎么来的,为什么叫控制反转,这些我认为都是表象而已。
这也是我所强调的思考。

对于老陆来讲,他是很牛的,我相信我写的任何一篇文章对他来都是垃圾,因为他都比我要懂得多。

所以从某种角度来讲,我的这种引导也是善意的,至少能够通俗的理解ioc他真正给我们带来了什么,能够说服我自己我的项目里可以放心的用他,而不再去问我们为什么要这么用。

其实我做过一些当中,有的分了很多层,也有接口,但new还是写在代码里,完成是为了接口而接口。有多少人困惑,又有多少人真正思考。再问有多少人思考并坚持找到答案?

59 楼 iday 2013-07-25  
zh_harry 写道
早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。--
downpour 写道
zh_harry 写道
downpour 写道
从一开始,理解就错了。所以我从来都不主张通过博客来表达所谓的心得体会,因为不正确的观点会通过博客散播开来造成对别人的误导。

你说说什么地方是错的呢?我错没关系,我可以接受,我最不能接受的是不说出错在哪?你用意何在呢?


问题是我有什么义务告诉你错在哪里?告诉你错了就已经是在提醒你注意了,要是你找不到你错在哪里,那么显然你就不该写博客谈所谓的心得体会。

写博客你可以阐述观点,但是必须要有引证来证明。你写一堆心得体会,但是没有东西证明你这体会是正确的,那显然是有问题的。我也写博客,但是我很少写心得体会,一般只会引用别人的观点,然后加以阐述。如果阐述自己的观点,一定找出旁证来说明。

我费力帮你搜了martin fowler的原文:http://martinfowler.com/bliki/InversionOfControl.html

引用
There's a big difference now in the flow of control between these programs - in particular the control of when the process_name and process_quest methods are called. In the command line form I control when these methods are called, but in the window example I don't. Instead I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form. The control is inverted - it calls me rather me calling the framework.


到底什么是控制反转?你的原文中的阐述:依赖对象的获得被反转。你看看和martin说的一样么?IoC和DI是完全2种不同的概念,这也是martin另外撰文阐述过:http://www.martinfowler.com/articles/injection.html。但是在你的博客中,却把2个东西说成是一个意思。

年轻人,态度决定一切。做技术如果不够严谨,光会思考也是不够的。少一分戾气,多一分执着。

"早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。--这不是我的原文,是martin说的,看到摘自维基百科了吗?再看spring技术内幕其中也是这句话

写博客你可以阐述观点,但是必须要有引证来证明难道这不算是证明吗?我觉得你太把自己当回事了,你的书我肯定不会买的!
维基百科原文地址:
http://zh.wikipedia.org/zh-cn/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC


建议你看一下英文版维基百科对于这段话的说明。另外陆老师的脾气怎么这么多年还没改改哇。
58 楼 zh_harry 2013-07-24  
老陆从头来没法引用了
你敢说ioc不是因为耦合度高而产生一种思想吗?我认为是为了解耦
而且我们在一点上已经达成一致了,透过表现看本质,你拍良心说,我这句话你看了吗?理解了吗?
57 楼 zh_harry 2013-07-24  
downpour 写道
zh_harry 写道


陆老师,首先对您的回复我表示感谢。
其实我早就回到问题本身了,而你还在纠结,我想问一句您真的看了我这篇回复了吗?
这是我回复的原话
关于IOC,他是一种思想,至于他到底是什么(控制反射、依赖注入或其他)我觉得并不重要,为什么会提出这种概念,是我们实际开发当中需要解耦,这是因为实际问题而产生一种思想和解决方案。注意我们要解决的是解耦,而依赖注入是一种实现手段。我不喜欢纠结于一个概念上而忘记事情的本质。
您再看看您的结论:
2者一个是理论,另一个偏实践。
难道不是一个意思吗?

我这块已经说得很清楚了。

还有在之前的讨论中,我也并非是在纠结是计文柯老师说得对还是您说得对,而是在讨论您应该对后辈一点尊重,您在回复过程中根本没有仔细看我的文章。
这次回复是这样,之前计老师引用维基百科您也是没有仔细看文章,而直接说我在误导。我希望的是得到您的理解以及大家的理解。您再回头看看您的回复,这完全是一种高高在上的感觉。我们分歧是在这里,您没有理解我


对于你的回复,我不得不说,你的水平已经低劣到我不想去逐一回复了。

IoC和解耦有个毛线关系啊,你说的和我说的完全车头彻底是2码子事情,居然还能被你理解成是一个意思,真是中国文字的悲哀。

你看看你的回复,一条在问“维基百科错了”,一条在问我是否在批评Spring技术内幕,另一条引用了我说的话然后表示鄙视。我还真心没看到一个和问题本质有关系的回复。

误导就是误导,错误就是错误,有啥好多纠结的。Javaeye从04年起一直到09年的讨论氛围一直就是用事实说话,驳斥对方的错误观点。我们的分歧就是明明是你错了,还死不认账,拿出的论据没一个站得住脚,还老觉得别人高高在上。你去翻翻过去的讨论文章,哪个不是把人18代祖宗都问候遍了。

如果没有水平和能力,就不要写博客出来丢人现眼。和论坛上有位同学一样,写了几百篇文章,只有1到2篇有点价值,这不是典型的浪费生命么。

downpour 写道
zh_harry 写道


陆老师,首先对您的回复我表示感谢。
其实我早就回到问题本身了,而你还在纠结,我想问一句您真的看了我这篇回复了吗?
这是我回复的原话
关于IOC,他是一种思想,至于他到底是什么(控制反射、依赖注入或其他)我觉得并不重要,为什么会提出这种概念,是我们实际开发当中需要解耦,这是因为实际问题而产生一种思想和解决方案。注意我们要解决的是解耦,而依赖注入是一种实现手段。我不喜欢纠结于一个概念上而忘记事情的本质。
您再看看您的结论:
2者一个是理论,另一个偏实践。
难道不是一个意思吗?

我这块已经说得很清楚了。

还有在之前的讨论中,我也并非是在纠结是计文柯老师说得对还是您说得对,而是在讨论您应该对后辈一点尊重,您在回复过程中根本没有仔细看我的文章。
这次回复是这样,之前计老师引用维基百科您也是没有仔细看文章,而直接说我在误导。我希望的是得到您的理解以及大家的理解。您再回头看看您的回复,这完全是一种高高在上的感觉。我们分歧是在这里,您没有理解我


对于你的回复,我不得不说,你的水平已经低劣到我不想去逐一回复了。

IoC和解耦有个毛线关系啊,你说的和我说的完全车头彻底是2码子事情,居然还能被你理解成是一个意思,真是中国文字的悲哀。

你看看你的回复,一条在问“维基百科错了”,一条在问我是否在批评Spring技术内幕,另一条引用了我说的话然后表示鄙视。我还真心没看到一个和问题本质有关系的回复。

误导就是误导,错误就是错误,有啥好多纠结的。Javaeye从04年起一直到09年的讨论氛围一直就是用事实说话,驳斥对方的错误观点。我们的分歧就是明明是你错了,还死不认账,拿出的论据没一个站得住脚,还老觉得别人高高在上。你去翻翻过去的讨论文章,哪个不是把人18代祖宗都问候遍了。

如果没有水平和能力,就不要写博客出来丢人现眼。和论坛上有位同学一样,写了几百篇文章,只有1到2篇有点价值,这不是典型的浪费生命么。

有失身份了啊。其实你一直死不赖帐。我说得是不是一个意思,让大家来评论。你太自以为是了。你这个人只抓住看到不爽的,却根本不看那些有意义的。不可理喻
56 楼 downpour 2013-07-24  
zh_harry 写道


陆老师,首先对您的回复我表示感谢。
其实我早就回到问题本身了,而你还在纠结,我想问一句您真的看了我这篇回复了吗?
这是我回复的原话
关于IOC,他是一种思想,至于他到底是什么(控制反射、依赖注入或其他)我觉得并不重要,为什么会提出这种概念,是我们实际开发当中需要解耦,这是因为实际问题而产生一种思想和解决方案。注意我们要解决的是解耦,而依赖注入是一种实现手段。我不喜欢纠结于一个概念上而忘记事情的本质。
您再看看您的结论:
2者一个是理论,另一个偏实践。
难道不是一个意思吗?

我这块已经说得很清楚了。

还有在之前的讨论中,我也并非是在纠结是计文柯老师说得对还是您说得对,而是在讨论您应该对后辈一点尊重,您在回复过程中根本没有仔细看我的文章。
这次回复是这样,之前计老师引用维基百科您也是没有仔细看文章,而直接说我在误导。我希望的是得到您的理解以及大家的理解。您再回头看看您的回复,这完全是一种高高在上的感觉。我们分歧是在这里,您没有理解我


对于你的回复,我不得不说,你的水平已经低劣到我不想去逐一回复了。

IoC和解耦有个毛线关系啊,你说的和我说的完全车头彻底是2码子事情,居然还能被你理解成是一个意思,真是中国文字的悲哀。

你看看你的回复,一条在问“维基百科错了”,一条在问我是否在批评Spring技术内幕,另一条引用了我说的话然后表示鄙视。我还真心没看到一个和问题本质有关系的回复。

误导就是误导,错误就是错误,有啥好多纠结的。Javaeye从04年起一直到09年的讨论氛围一直就是用事实说话,驳斥对方的错误观点。我们的分歧就是明明是你错了,还死不认账,拿出的论据没一个站得住脚,还老觉得别人高高在上。你去翻翻过去的讨论文章,哪个不是把人18代祖宗都问候遍了。

如果没有水平和能力,就不要写博客出来丢人现眼。和论坛上有位同学一样,写了几百篇文章,只有1到2篇有点价值,这不是典型的浪费生命么。
55 楼 zh_harry 2013-07-24  
beyondyuefei 写道
downpour 写道
其实IoC这个概念已经被误导了很多年,由于Java和Spring Framework的兴起,导致了IoC的本质很早就被遗忘了。如果仔细去看Martin的文章,他在描述IoC概念的时候,用的是Ruby语言,并且这个例子和所谓的依赖注入也没有多大关系。

现在市面上绝大多数的书籍对于IoC的理解都不是Martin的原意。这一点其实早在05年年底的时候我就在论坛上和很多前辈讨论得很清楚。可惜的是很多年过去了,依然没有人能够把这个问题的本质说清楚,包括计文柯老师的书、陈雄华老师的书,我认为在这个方面都是错误的。不过论坛里面有一个写设计模式的同学,对这个问题倒是说得有理有据,还引用了Martin的原文,可以参考。

IoC这个概念时至今日已经没有再挖掘的必要,其实错也就错了,它究竟是一种思想还是一种实践方式,都已经错了那么多年,到底是什么,目前来讲已经不重要了。我也好久没上技术网站,随意翻了博客首页的几篇文章才随性回了几贴。

可惜05年的原帖已经找不到,我可以把当时我们讨论的一些要点写给你,仅供参考。

1. 究竟为什么会产生IoC?其实Martin说的非常清楚:如果没有对象协作,根本无所谓IoC。就像Martin在他的文章中所举的例子,他的第一个程序,所有的逻辑控制都在主程序main中,一贯到底,没有和其他的对象有任何交互,所以主程序main具有对逻辑的绝对控制权。而第二个程序,加入了windowing system,引入了其他对象。此时,What is Your Name?这些逻辑被封装在了其他对象之中。一旦被封装,主程序就直接失去了对逻辑的绝对控制权,把逻辑的控制权交给了协作对象。这叫做逻辑控制权反转。

2. 到底什么被反转了?Martin说得也很明白:I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form.也就是说,程序的控制逻辑被反转了,而不是什么依赖对象的获得、依赖对象的创建。在另一篇文章中,Martin是这么说的:The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.这东西要我翻译一下么?

3. IoC最初到底用来干嘛?Martin的文章是这么说的: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.你看看,IoC和什么依赖对象的获得,有一毛钱关系嘛?人家明明说的是,Framework拥有对主程序的控制权,IoC被用于设定用户自定义的扩展点。

4. 为什么IoC容易和DI混淆?因为Spring Framework的兴起,构建了一个第三方的容器(Container),而这些Container都号称great因为它们真心实现了IoC。而对此Martin的评述是:When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. Inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.所以,其实Martin对这些所谓容器的评价是,它们顶多实现的是DI,而IoC只是一种更加High Level的理念。就像汽车必须要用轮子一样。而Spring实在是太成功了,以至于大家都忘记了IoC本身其实就像汽车用轮子那么简单。

5. 小小结论:IoC描述的其实是对象之间的协作关系以及程序执行逻辑的哲学思想。而DI描述的确是对象之间如何建立起可运行的依赖关系。其实2者一个是理论,另一个偏实践。

楼主,你有个很大的问题就是始终不能回归到问题本身。你一直在纠结维基百科怎么会出错,某某人写的书怎么会出错。某某人写的书,理解也不对。如果你想了解一个问题的原貌,唯一的途径其实就是研究这个问题最原始的出处,这才是治学之道。

不过反过来想,Java已经发展了10多年了,你确定还有必要去炒这些冷饭?这些东西05年就已经有定论了。8年过去了,抗战都结束了。搞点有实际意义的东西不好么?


    我代表广大读者问问你,你的 spring mvc 那本书到底什么时候能出版?从去年就开始忽悠了,到现在一点消息都没有,到底什么情况?

你还挺关心老陆,关心关心我不行吗?都让他欺负成啥样了
54 楼 beyondyuefei 2013-07-24  
downpour 写道
其实IoC这个概念已经被误导了很多年,由于Java和Spring Framework的兴起,导致了IoC的本质很早就被遗忘了。如果仔细去看Martin的文章,他在描述IoC概念的时候,用的是Ruby语言,并且这个例子和所谓的依赖注入也没有多大关系。

现在市面上绝大多数的书籍对于IoC的理解都不是Martin的原意。这一点其实早在05年年底的时候我就在论坛上和很多前辈讨论得很清楚。可惜的是很多年过去了,依然没有人能够把这个问题的本质说清楚,包括计文柯老师的书、陈雄华老师的书,我认为在这个方面都是错误的。不过论坛里面有一个写设计模式的同学,对这个问题倒是说得有理有据,还引用了Martin的原文,可以参考。

IoC这个概念时至今日已经没有再挖掘的必要,其实错也就错了,它究竟是一种思想还是一种实践方式,都已经错了那么多年,到底是什么,目前来讲已经不重要了。我也好久没上技术网站,随意翻了博客首页的几篇文章才随性回了几贴。

可惜05年的原帖已经找不到,我可以把当时我们讨论的一些要点写给你,仅供参考。

1. 究竟为什么会产生IoC?其实Martin说的非常清楚:如果没有对象协作,根本无所谓IoC。就像Martin在他的文章中所举的例子,他的第一个程序,所有的逻辑控制都在主程序main中,一贯到底,没有和其他的对象有任何交互,所以主程序main具有对逻辑的绝对控制权。而第二个程序,加入了windowing system,引入了其他对象。此时,What is Your Name?这些逻辑被封装在了其他对象之中。一旦被封装,主程序就直接失去了对逻辑的绝对控制权,把逻辑的控制权交给了协作对象。这叫做逻辑控制权反转。

2. 到底什么被反转了?Martin说得也很明白:I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form.也就是说,程序的控制逻辑被反转了,而不是什么依赖对象的获得、依赖对象的创建。在另一篇文章中,Martin是这么说的:The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.这东西要我翻译一下么?

3. IoC最初到底用来干嘛?Martin的文章是这么说的: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.你看看,IoC和什么依赖对象的获得,有一毛钱关系嘛?人家明明说的是,Framework拥有对主程序的控制权,IoC被用于设定用户自定义的扩展点。

4. 为什么IoC容易和DI混淆?因为Spring Framework的兴起,构建了一个第三方的容器(Container),而这些Container都号称great因为它们真心实现了IoC。而对此Martin的评述是:When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. Inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.所以,其实Martin对这些所谓容器的评价是,它们顶多实现的是DI,而IoC只是一种更加High Level的理念。就像汽车必须要用轮子一样。而Spring实在是太成功了,以至于大家都忘记了IoC本身其实就像汽车用轮子那么简单。

5. 小小结论:IoC描述的其实是对象之间的协作关系以及程序执行逻辑的哲学思想。而DI描述的确是对象之间如何建立起可运行的依赖关系。其实2者一个是理论,另一个偏实践。

楼主,你有个很大的问题就是始终不能回归到问题本身。你一直在纠结维基百科怎么会出错,某某人写的书怎么会出错。某某人写的书,理解也不对。如果你想了解一个问题的原貌,唯一的途径其实就是研究这个问题最原始的出处,这才是治学之道。

不过反过来想,Java已经发展了10多年了,你确定还有必要去炒这些冷饭?这些东西05年就已经有定论了。8年过去了,抗战都结束了。搞点有实际意义的东西不好么?


    我代表广大读者问问你,你的 spring mvc 那本书到底什么时候能出版?从去年就开始忽悠了,到现在一点消息都没有,到底什么情况?
53 楼 zh_harry 2013-07-24  
downpour 写道
其实IoC这个概念已经被误导了很多年,由于Java和Spring Framework的兴起,导致了IoC的本质很早就被遗忘了。如果仔细去看Martin的文章,他在描述IoC概念的时候,用的是Ruby语言,并且这个例子和所谓的依赖注入也没有多大关系。

现在市面上绝大多数的书籍对于IoC的理解都不是Martin的原意。这一点其实早在05年年底的时候我就在论坛上和很多前辈讨论得很清楚。可惜的是很多年过去了,依然没有人能够把这个问题的本质说清楚,包括计文柯老师的书、陈雄华老师的书,我认为在这个方面都是错误的。不过论坛里面有一个写设计模式的同学,对这个问题倒是说得有理有据,还引用了Martin的原文,可以参考。

IoC这个概念时至今日已经没有再挖掘的必要,其实错也就错了,它究竟是一种思想还是一种实践方式,都已经错了那么多年,到底是什么,目前来讲已经不重要了。我也好久没上技术网站,随意翻了博客首页的几篇文章才随性回了几贴。

可惜05年的原帖已经找不到,我可以把当时我们讨论的一些要点写给你,仅供参考。

1. 究竟为什么会产生IoC?其实Martin说的非常清楚:如果没有对象协作,根本无所谓IoC。就像Martin在他的文章中所举的例子,他的第一个程序,所有的逻辑控制都在主程序main中,一贯到底,没有和其他的对象有任何交互,所以主程序main具有对逻辑的绝对控制权。而第二个程序,加入了windowing system,引入了其他对象。此时,What is Your Name?这些逻辑被封装在了其他对象之中。一旦被封装,主程序就直接失去了对逻辑的绝对控制权,把逻辑的控制权交给了协作对象。这叫做逻辑控制权反转。

2. 到底什么被反转了?Martin说得也很明白:I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form.也就是说,程序的控制逻辑被反转了,而不是什么依赖对象的获得、依赖对象的创建。在另一篇文章中,Martin是这么说的:The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.这东西要我翻译一下么?

3. IoC最初到底用来干嘛?Martin的文章是这么说的: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.你看看,IoC和什么依赖对象的获得,有一毛钱关系嘛?人家明明说的是,Framework拥有对主程序的控制权,IoC被用于设定用户自定义的扩展点。

4. 为什么IoC容易和DI混淆?因为Spring Framework的兴起,构建了一个第三方的容器(Container),而这些Container都号称great因为它们真心实现了IoC。而对此Martin的评述是:When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. Inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.所以,其实Martin对这些所谓容器的评价是,它们顶多实现的是DI,而IoC只是一种更加High Level的理念。就像汽车必须要用轮子一样。而Spring实在是太成功了,以至于大家都忘记了IoC本身其实就像汽车用轮子那么简单。

5. 小小结论:IoC描述的其实是对象之间的协作关系以及程序执行逻辑的哲学思想。而DI描述的确是对象之间如何建立起可运行的依赖关系。其实2者一个是理论,另一个偏实践。

楼主,你有个很大的问题就是始终不能回归到问题本身。你一直在纠结维基百科怎么会出错,某某人写的书怎么会出错。某某人写的书,理解也不对。如果你想了解一个问题的原貌,唯一的途径其实就是研究这个问题最原始的出处,这才是治学之道。

不过反过来想,Java已经发展了10多年了,你确定还有必要去炒这些冷饭?这些东西05年就已经有定论了。8年过去了,抗战都结束了。搞点有实际意义的东西不好么?


陆老师,首先对您的回复我表示感谢。
其实我早就回到问题本身了,而你还在纠结,我想问一句您真的看了我这篇回复了吗?
这是我回复的原话
关于IOC,他是一种思想,至于他到底是什么(控制反射、依赖注入或其他)我觉得并不重要,为什么会提出这种概念,是我们实际开发当中需要解耦,这是因为实际问题而产生一种思想和解决方案。注意我们要解决的是解耦,而依赖注入是一种实现手段。我不喜欢纠结于一个概念上而忘记事情的本质。
您再看看您的结论:
2者一个是理论,另一个偏实践。
难道不是一个意思吗?

我这块已经说得很清楚了。

还有在之前的讨论中,我也并非是在纠结是计文柯老师说得对还是您说得对,而是在讨论您应该对后辈一点尊重,您在回复过程中根本没有仔细看我的文章。
这次回复是这样,之前计老师引用维基百科您也是没有仔细看文章,而直接说我在误导。我希望的是得到您的理解以及大家的理解。您再回头看看您的回复,这完全是一种高高在上的感觉。我们分歧是在这里,您没有理解我
52 楼 downpour 2013-07-24  
其实IoC这个概念已经被误导了很多年,由于Java和Spring Framework的兴起,导致了IoC的本质很早就被遗忘了。如果仔细去看Martin的文章,他在描述IoC概念的时候,用的是Ruby语言,并且这个例子和所谓的依赖注入也没有多大关系。

现在市面上绝大多数的书籍对于IoC的理解都不是Martin的原意。这一点其实早在05年年底的时候我就在论坛上和很多前辈讨论得很清楚。可惜的是很多年过去了,依然没有人能够把这个问题的本质说清楚,包括计文柯老师的书、陈雄华老师的书,我认为在这个方面都是错误的。不过论坛里面有一个写设计模式的同学,对这个问题倒是说得有理有据,还引用了Martin的原文,可以参考。

IoC这个概念时至今日已经没有再挖掘的必要,其实错也就错了,它究竟是一种思想还是一种实践方式,都已经错了那么多年,到底是什么,目前来讲已经不重要了。我也好久没上技术网站,随意翻了博客首页的几篇文章才随性回了几贴。

可惜05年的原帖已经找不到,我可以把当时我们讨论的一些要点写给你,仅供参考。

1. 究竟为什么会产生IoC?其实Martin说的非常清楚:如果没有对象协作,根本无所谓IoC。就像Martin在他的文章中所举的例子,他的第一个程序,所有的逻辑控制都在主程序main中,一贯到底,没有和其他的对象有任何交互,所以主程序main具有对逻辑的绝对控制权。而第二个程序,加入了windowing system,引入了其他对象。此时,What is Your Name?这些逻辑被封装在了其他对象之中。一旦被封装,主程序就直接失去了对逻辑的绝对控制权,把逻辑的控制权交给了协作对象。这叫做逻辑控制权反转。

2. 到底什么被反转了?Martin说得也很明白:I hand control over to the windowing system (with the Tk.mainloop command). It then decides when to call my methods, based on the bindings I made when creating the form.也就是说,程序的控制逻辑被反转了,而不是什么依赖对象的获得、依赖对象的创建。在另一篇文章中,Martin是这么说的:The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.这东西要我翻译一下么?

3. IoC最初到底用来干嘛?Martin的文章是这么说的: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.你看看,IoC和什么依赖对象的获得,有一毛钱关系嘛?人家明明说的是,Framework拥有对主程序的控制权,IoC被用于设定用户自定义的扩展点。

4. 为什么IoC容易和DI混淆?因为Spring Framework的兴起,构建了一个第三方的容器(Container),而这些Container都号称great因为它们真心实现了IoC。而对此Martin的评述是:When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. Inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.所以,其实Martin对这些所谓容器的评价是,它们顶多实现的是DI,而IoC只是一种更加High Level的理念。就像汽车必须要用轮子一样。而Spring实在是太成功了,以至于大家都忘记了IoC本身其实就像汽车用轮子那么简单。

5. 小小结论:IoC描述的其实是对象之间的协作关系以及程序执行逻辑的哲学思想。而DI描述的确是对象之间如何建立起可运行的依赖关系。其实2者一个是理论,另一个偏实践。

楼主,你有个很大的问题就是始终不能回归到问题本身。你一直在纠结维基百科怎么会出错,某某人写的书怎么会出错。某某人写的书,理解也不对。如果你想了解一个问题的原貌,唯一的途径其实就是研究这个问题最原始的出处,这才是治学之道。

不过反过来想,Java已经发展了10多年了,你确定还有必要去炒这些冷饭?这些东西05年就已经有定论了。8年过去了,抗战都结束了。搞点有实际意义的东西不好么?
51 楼 zh_harry 2013-07-24  
看了大家的评论,我也学到了很多,有些值得我反省,我在回复中也承认了要学习和改进的地方,但有些评论是自命清高的。
一种人是自以为在业界很牛,我想说的是在我们身边不缺牛人。我所主张的是简单,让大家能够真正的领悟到事情的本质。
   而不是象有些所谓的砖家,先把自己绕蒙,再努力把别人绕蒙,最后说只有我的理解是对的,你们说得都是不对的等等。

  关于IOC,他是一种思想,至于他到底是什么(控制反射、依赖注入或其他)我觉得并不重要,为什么会提出这种概念,是我们实际开发当中需要解耦,这是因为实际问题而产生一种思想和解决方案。注意我们要解决的是解耦,而依赖注入是一种实现手段。我不喜欢纠结于一个概念上而忘记事情的本质。

  再有,我不想说我年纪有多大,这跟年龄没有关系,但是我要澄清,我不是某人想象中的年轻人。
  还有一种人是干了N的技术的,沟通上存在问题比较大,以至于没办法一直coding的人。做技术久,喜欢做,不是坏事,但是要有好的思维方法(思维是可以学习的)。但是钻牛角尖确实是无意义的。

  这些都是我经过多年的思考、迷惑和沉淀之后的积累,有人说我把控制反转和依赖注入混为一谈是误导。其实我在大二的开始研究java那时侯就有这些概念,到现在快有10年了。曾经看过很多真正的误导成分,最后看到spring 技术内幕才觉得这样讲是很好理解的。我想表达的是让大家少走弯路,真正把我的思考过程分享给大家,反而有些所谓的专家过来抨击,你觉得这样做对一个"年轻人"有帮助吗?

各位可以看一下这些评论,如果觉得好请顶一个,觉得确实在误就踩吧。

50 楼 beyondyuefei 2013-07-23  
Definition of IOC :

Inversion of control is based on the phenomenon that says when ever dependency between two classes (say class A and class B) now if A needs to access the methods of B then following our traditional approach, we go ahead and create an object of B in A.

But as the fact of matter B is there to serve A but not A serving B creating objects for B.

So in IOC the class B will try to inject its object into A rather than A creating object of B. so the control is reversed during the run time now spring container takes care which class object to inject into other class. So here class B inject its dependency in class A using constructor or setter.

So here the statement works "Don't call me, I call you", class B calls class A even if class A needs the object B.

说的什么逻辑执行能力完全是扯蛋
这和什么逻辑执行能力没有半点关系
就是由谁负责创建(或注入)
49 楼 zh_harry 2013-07-23  
downpour 写道
zh_harry 写道

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。


不好意思,看不起你。

    对象之间协作的真正含义是对象通过其依赖对象的帮助,完成其业务逻辑的过程,而动作特性的对象的嵌套引用,是对象之间协作完成业务逻辑的基本途径,也是对象之间形成依赖关系的根本原因,在这种情况下,每个对象不得不依赖于其协作的对象(也就是它所依赖的对象)的引用和构建。

   通俗来说:每个对象自身对于逻辑的执行能力,被其所依赖的对象反向控制了,这也就是 控制反转的本质含义。(IOC)


这就是你所谓的ioc?还看不起姿态别那么高。
48 楼 zh_harry 2013-07-23  
beyondyuefei 写道
downpour 写道
zh_harry 写道

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。


不好意思,看不起你。


你有时间在这边和人家 YY 争论,我倒想问问你,你说好的 spring mvc 的书呢?到底什么时候能出?

他说他不写书了,这样的人写书谁买啊。省省吧,还不如看我博客还不要钱
47 楼 beyondyuefei 2013-07-23  
downpour 写道
zh_harry 写道

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。


不好意思,看不起你。


你有时间在这边和人家 YY 争论,我倒想问问你,你说好的 spring mvc 的书呢?到底什么时候能出?
46 楼 zh_harry 2013-07-23  
downpour 写道
zh_harry 写道

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。


不好意思,看不起你。

晕,你够很
45 楼 downpour 2013-07-23  
zh_harry 写道

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。


不好意思,看不起你。
44 楼 zh_harry 2013-07-23  
downpour 写道
zh_harry 写道

还有这句话是spring内幕中引用维基百科的。你这样说就是在批评spring技术内幕不对喽?


人家写得不对的地方多了去了,但是你是否能够辨别出这东西对不对就是你自己的问题了。如果你所谓的思考始终建立在一些原本就是错误的基础之上,那再怎么思考也是有一定局限性的。

另外,我已不做技术很久,纯粹是和你闹着玩的,也无兴趣去看所谓的框架源码。讨论就此结束。

呵呵,我也跟你闹着玩呢,还真禁得起闹,所以想加你好友嘛,不做技术更好。看得起我就加我。
对我个人而言,对这块的理解无所谓了,我觉得我把握住了核心。
43 楼 downpour 2013-07-23  
zh_harry 写道

还有这句话是spring内幕中引用维基百科的。你这样说就是在批评spring技术内幕不对喽?


人家写得不对的地方多了去了,但是你是否能够辨别出这东西对不对就是你自己的问题了。如果你所谓的思考始终建立在一些原本就是错误的基础之上,那再怎么思考也是有一定局限性的。

另外,我已不做技术很久,纯粹是和你闹着玩的,也无兴趣去看所谓的框架源码。讨论就此结束。
42 楼 zh_harry 2013-07-23  
downpour 写道
我已经说了,你已经误入歧途,只可惜你戾气太重,始终不能自拔。

你的观点来自于维基百科。可惜的是,维基百科也是普通人编辑的,谁告诉你维基百科的观点就是正确的?你要引用一个人的观点,你就必须用他自己说的话来证明这个观点是正确的,你总不至于引用一个维基百科的东西,陈述了一个和他的观点截然不同的东西,然后告诉大家这个观点是正确的吧。

我已经列了martin的原文给你了,仔细读原文,相信你还是能够理解他到底在说什么的。由于你过于纠结于其他的问题,而忽略了martin到底在描述IoC的时候说了些什么。从你最新的回复中可以看到,你依旧把两个截然不同的概念混为一谈,可见你根本没有细读并思考martin的文章。

我看了一些你其他的文章,对Spring的理解在我看来其实也有问题。不过那个你可以有自己的观点,因为这并不影响对一个早已有定论的概念(例如IoC)的阐述和传播。

还有这句话是spring内幕中引用维基百科的。你这样说就是在批评spring技术内幕不对喽?
41 楼 zh_harry 2013-07-23  
downpour 写道
我已经说了,你已经误入歧途,只可惜你戾气太重,始终不能自拔。

你的观点来自于维基百科。可惜的是,维基百科也是普通人编辑的,谁告诉你维基百科的观点就是正确的?你要引用一个人的观点,你就必须用他自己说的话来证明这个观点是正确的,你总不至于引用一个维基百科的东西,陈述了一个和他的观点截然不同的东西,然后告诉大家这个观点是正确的吧。

我已经列了martin的原文给你了,仔细读原文,相信你还是能够理解他到底在说什么的。由于你过于纠结于其他的问题,而忽略了martin到底在描述IoC的时候说了些什么。从你最新的回复中可以看到,你依旧把两个截然不同的概念混为一谈,可见你根本没有细读并思考martin的文章。

我看了一些你其他的文章,对Spring的理解在我看来其实也有问题。不过那个你可以有自己的观点,因为这并不影响对一个早已有定论的概念(例如IoC)的阐述和传播。

老陆,谢谢你还有勇气给我回复,有空看看我的源码框架。这些文章都是为这个框架打基础的。我说了这些东西不用太过纠结,真正能用起来,怎么容易理解就怎么理解。以无法为有法,这个观点可能对大家有影响。所以我在回复中也强调了更重要的是自己辨别和思考。

相关推荐

    JAVA设计模式之IOC实战02

    JAVA设计模式之IOC实战02

    Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程.doc

    Spring 框架系列(7)- Spring IOC 实现原理详解之 IOC 初始化流程 本文将详细解释 Spring 框架中的 IOC(Inversion of Control,控制反转)实现原理之 IOC 初始化流程。IOC 是一种软件设计模式,用于将软件系统中...

    Spring之IOC示例

    在IT行业中,Spring框架是Java开发领域中一个极为...通过阅读《Spring之IOC示例》这篇博客(博文链接:https://huangminwen.iteye.com/blog/1041298),可以更深入地理解Spring的IOC机制,并学习如何在实际项目中应用。

    自己实现ioc实例demo

    在IT行业中,依赖注入(IOC,Inversion of Control)是一种设计模式,它使得应用程序的组件之间解耦,提高了代码的可测试性和可维护性。在这个“自己实现ioc实例demo”中,我们将探讨如何通过XPath解析XML文件来实现...

    springIoc实现原理

    Spring Ioc(Inversion of Control,控制反转)是Spring框架的核心特性之一,它改变了传统应用程序中对象的创建和管理方式。在传统的软件设计中,对象的创建和依赖关系的维护通常由代码自身来完成,而在Spring Ioc中...

    JAVA设计模式之IOC实战01

    JAVA设计模式之IOC实战01

    Spring中IoC优点与缺点解析

    IoC 容器在 Spring 框架中是一种非常有用的设计模式,它可以简化对象的创建和管理,解耦合对象之间的依赖关系,提高开发效率和降低出错率。但是,使用 IoC 容器也可能会增加对象生成的步骤和效率损耗。

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 <!-- 配置数据源 --> destroy-method="close"> <value>org.gjt.mm.mysql.Driver <value>jdbc:mysql://localhost:3306/demo <value>root ...

    Android进阶——框架打造之IOC框架

    Android进阶——框架打造之IOC框架 实现通过Id找到控件的功能 实现通过Id找到Color、String资源 实现绑定view的点击事件、长按事件 实现绑定SetContentView 实现绑定网络的检测功能

    图片转IOC图标工具

    使用.IOC图标可以确保在不同设备上显示的图标大小适中、清晰无损,提升用户体验。而这款工具则简化了这一过程,使得开发者无需手动调整每个尺寸,大大提高了工作效率。 首先,我们来了解一下.IOC图标的组成部分。一...

    雷赛IOC0640.rar

    在压缩包子文件的文件名称列表中,仅有一个条目“雷赛IOC0640”,这可能意味着压缩包内包含的是关于IOC0640的综合资料,除了已知的DMC2210硬件手册外,还可能有用户手册、软件驱动、配置工具、技术规格表、示例代码...

    IoC 依赖注入 技术总结

    静态 IoC 的优点是实现简单、效率高,仅需要在客户端 XML 文件变更时,才实现类的生成、编译等工作,以后在运行期间直接调用 Class 文件即可,编译期已经实现依赖注入,具有编译期检查特点,占用较少的空间而赢得...

    JavaEE Spring IoC入门

    在Spring框架中,IoC容器是核心组件,它负责创建、装配和管理对象。IoC容器通过读取XML配置文件来理解对象及其依赖关系,然后自动进行实例化和装配。这样,开发者不再需要手动创建和管理对象,而是将这些控制权交给...

    IoC小例子(了解一下IoC设计模式入门)

    IoC设计模式的实现通常依赖于容器,如Spring框架在Java中就是一个著名的IoC容器。开发者可以通过XML配置、注解或者编程式的方式来定义对象及其依赖关系。例如,在Spring中,我们可以在XML配置文件中定义Bean(代表一...

    iocdemo.rar

    在本示例"iocdemo.rar"中,我们将探讨如何模仿Spring的IoC原理,通过XML配置和注解两种方式进行Bean的管理。 **控制反转(IoC)** IoC意味着应用程序的控制权由传统的程序流程控制转向了外部容器,即Spring框架。在...

    IOC练习事列

    在本例中,我们将探讨一个基于C#实现的简单IOC练习。 **容器机制**: 在IOC中,容器是负责管理对象生命周期和对象间依赖关系的核心组件。它会根据配置或编程方式来决定何时创建对象、如何创建对象以及对象之间的...

    IOC模式 c#经典例子

    IOC(Inversion of Control,控制反转)模式是一种软件设计原则,它在面向对象编程中用于解耦组件之间的依赖关系。C#中实现IOC的一种常见方式是通过依赖注入(Dependency Injection,DI)。在这个“IOC模式 c#经典...

    spring ioc

    Spring 是一个广泛应用的 Java 应用开发框架,其核心特性之一就是IOC,它极大地简化了软件组件之间的依赖管理。在本文中,我们将深入探讨 Spring IOC 的概念、工作原理以及如何在实际项目中应用。 首先,理解 IOC ...

    SpringIoC的简单实现

    【SSH进阶之路】一步步重构容器实现Spring的IoC——解决容器对组件的“侵入式”管理的两种方案--服务定位器和IoC容器(九) 【SSH进阶之路】一步步重构容器实现Spring的IoC——工厂+反射+配置文件实现IoC容器(十)

    IOC详解IOC详解IOC详解IOC详解

    控制反转(IOC,Inversion of Control)是一种设计模式,它在软件工程中被广泛应用,特别是在Java开发中。IoC的核心思想是将对象的创建和管理权交给一个外部容器,而不是让对象自行创建和管理依赖。这有助于降低耦合...

Global site tag (gtag.js) - Google Analytics