`
arthurln
  • 浏览: 42406 次
社区版块
存档分类
最新评论

关于IoC与DI(一)

阅读更多
  对于新技术反映比较慢,guice出来很久了,也只是看过一些简短的介绍而已。常常看到关于它和spring的比较,并且大都认为guice略胜一筹,这让我也忍不住想自己来比较一番。spring也有段时间没用了,所以就先到spring的网站瞅了一眼文档。因为同是IoC和DI容器,要比当然从这方面比,所以看文档的时候也更多的关注了这一部分。Chapter 1. Introduction(http://static.springframework.org/spring/docs/2.0.x/reference/introduction.html)右边灰色小框子里边的一段背景介绍引起了我对IoC和DI概念的兴趣。原文如下:

引用
In early 2004, Martin Fowler asked the readers of his site: when talking about Inversion of Control: “the question is, what aspect of control are [they] inverting?”. Fowler then suggested renaming the principle (or at least giving it a more self-explanatory name), and started to use the term Dependency Injection. His article then continued to explain the ideas underpinning the Inversion of Control (IoC) and Dependency Injection (DI) principle.
If you need a decent insight into IoC and DI, please do refer to said article : http://martinfowler.com/articles/injection.html.

  看到这里我就有点惭愧了,虽然很长一段时间都认为自己在使用IoC和DI,并且也自认为明白为什么要这么做,但是对于“ What aspect of control are [they] inverting?”还真就说不清楚。于是只好老老实实点开Martin Fowler在04年写的文章,认真补习一下。
  IoC(Inversion Of Control),通常译为控制反转,意思是程序将自己的控制权交给别人(系统,框架等),更具体的说就是你的程序写好了,什么时候调用就不由你来决定了。有一个非常经典的法则来形容这种情况——好莱坞法则(Hollywood Principle - "Don't call us, we'll call you"),就好像系统对某一功能模块说:你不要烦我了,用到你的时候我自然会叫你的。
  在我印象里最早接触到的经典IoC应用应该是高中用VB写的程序。写VB程序无非就是编写针对画面上的每一个控件(文本框,按钮等)的事件响应代码片断。在写得时候,没法控制每一个事件的发生时间,这些都是由基于消息机制的系统来响应用户请求后调用的。也就是说将具体的实现(依赖)推后到了运行的时候。比较流行的另一种说法就是,将互相依赖的模块解耦(decouple)。
  看过《重构》一书的人都应该对作者将编码和设计中的不良做法比做“bad smell”的说法印象深刻,而模块之间的高度耦合被公认为是最糟糕的几种味道之一。IoC就是解决这类问题的最好的除臭剂。所以IoC是一种方法,是设计思想,而不是什么高级的技术或者特性。Martin Fowler在它的文章中讽刺那些标榜自己的系统使用了IoC技术或者具有IoC特性的人就像某人在说:看,我的车很特别,因为它有轮子。他还举了一个很幼稚的例子,来证明IoC的平凡。现在我就举一个更幼稚的例子,这可能是我们大部分人小学就写过的程序(如果你参加过计算机培训班)。

// NaiveIoC.c
void one(){
	printf("one\n");
}

void notOne(){
	printf("not one\n");
}

void print(int i){
	if(1==i)
		one();
	else
		notOne();
}

main() {
	int x;
	printf("input number:\n");
	scanf("%i",&x);
	print(x);
}


  在这个例子里,可以把print方法看作一个服务提供者,而one和notOne方法则是它能够提供的两种服务,main方法依赖于print所提供的服务,而使用哪种具体的print服务则是在运行时根据用户输入而决定的。在这个例子中,main方法自己扮演了IoC框架和服务使用者两个角色。
  之所以用C语言来举例,并且在前边的描述中使用“模块”而不是“对象”,只是想说明,IoC的实践早在面向对象的开发方式出现前就已经存在了,只不过没有人去总结而已。它既不神秘,也不高深(指思想本身)。就像其他那些最简单但却最经典的理论一样平易近人。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics