zoukankan      html  css  js  c++  java
  • IOC:Inversion Of Control控制反转

         换了新公司,公司的项目中有用到Castle,第一次接触,便去了解了一下,其下有很多的子项目,感觉很强大,值得深入的学习。Castle官网:http://castleproject.org/。园子里介绍Castle的文章也很多,推荐两个:http://terrylee.cnblogs.com/archive/2006/04/28/castl_ioc_article.htmlhttp://www.cnblogs.com/wj/archive/2005/06/22/179357.html。园子里这些大牛们写这些文章都是05年左右的,到现在Castle也是发生了不少的变化,例如代码的方式,像其中简单例子中将组件加入IOC容器方法,但是其中涉及的思想或者思路还是一样的。

         最先了解的就是称之为.net和silverlight可用的成熟的IOC容器的Windsor Container.Windsor是什么,Windsor是IOC容器。理解了IOC,那Windsor能在我们项目中起什么作用,我们什么时候要用到它,这些就不在是问题了。什么是IOC呢??大牛们同时指向了一篇文章:Inversion of Control Containers and the Dependency Injection pattern。谁写的,就不说了,早就听说过大名,甚至还拜读过大作,但不熟。E文的,还老长,耐着性子看了个半截,一个感受:E文不好害死人啊,我把N多年的E文学习80%都还给社会了。靠着仅有的语感和救命的一篇文章:http://www.cnblogs.com/yycilpppp/archive/2007/01/08/615011.html,才让我对IOC的概念似乎有些懂了。

         IOC,翻译来就是控制反转,其实理解成为控制转移才更贴近实际,也就是控制权的转移。Martin Fowler所说的:不是说你说你用了IOC,你的项目就很NB了,IOC是框架的基本特征。例如我们.net的开发网站用到的web form框架,从用户请求网页开始,控件权在框架手中,但是本身框架提供很多供我们开发的接口、扩展,例如我们在Page_Load中写了一些代码,这其中就有IOC的概念,执行到Page_Load时,控制权就从框架转移到了我们代码里,我们的代码就可以控制整个的或者部分的执行了,执行完毕之后,再次返还给框架,框架再去负责运行其它的要运行的东西。

         这样做有什么好处呢,就像是前面所说的web form,我们利用web form,你可以写你的逻辑,我可以写的逻辑,如果没有这个东西,那从整个请求开始运行什么都要我们去执行,那后果。。。。但是映射到我们的项目中,我们又不开发框架,我们用的着吗??就像框架,我们做的项目,你可以很容易的像在网页中写Page_Load那样轻易的替换你需要变更的逻辑,那不是可以很轻易的面对一些需求的变化了吗。装B的说就是脱耦。

         为什么Castle Windsor/spring等等符合IOC的理念,它们主要解决什么问题呢?因为他们转移一些控制权到自己手里,它们接管了对象的创建、销毁等的控制权。他们是为了解决项目中组件的相互依赖问题的,他们要达到的目的就是可以在运行中替换组件,也就是所说的以插件的方式运行。所说来就是我们只负责编写负责各个职责的模块,而各个模块的依赖关系则交给我们的IOC容器去实现或者按照我们的配置由IOC去实现了。怎么个实现法,Windsor是利用自动装配,自动装配怎么实现的,研究windsor的源码吧,这里没有本事说清。和框架的IOC不一样,像windsor这种IOC的方式被取名叫做Dependency Injection 依赖注入。

          依赖注入又分三种:构造注入,设置注入,接口注入。

          举例说明:

    1,构造注入:构造函数中设置要引用的对象

        class LogHelper
        {
            private LogWriter _log;
            public LogHelper(LogWriter log)
            {
                _log = log;
            }
        }

    2,设置注入    

        class LogHelper
        {
            private LogWriter _log;
            public void SetLogWriter(LogWriter log)
            {
                _log = log;
            }
        }

    3,接口注入    

        class LogHelper
        {
            private ILog _log;
            public LogHelper(ILog log)
            {
                _log = log;
            }
        }

    我们可以看到,这些都是为了降低组件间的耦合,可以让我们代码时获得更大的灵活性。

    举个windsor应用的简单例子,只有调用时的代码。

                //    调用1
                LogHelper log = new LogHelper(new UserLog());
    
                log.WriteLog("some error happen in user system.");
    
                //   调用2
                IWindsorContainer container = new WindsorContainer(); 
    
                container.Register(Component.For<ILog>().ImplementedBy<UserLog>().Named("userlog"));
                container.Register(Component.For<LogHelper>().Named("helper"));
    
                LogHelper log2 = (LogHelper)container.Resolve<LogHelper>("helper");
    
                log2.WriteLog("some error happen in user system from ioc.");

         其中UserLog实现了ILog,这个例子不足以说明IOC怎么实现了以插件的形式工作的,但是我们可以从log2的调用中看到,在调用2中我们并没有调用LogHelper的构造函数,我们只是从容器中取出我们想要的对象,Castle就自动的为我们实现我们想要的一切。调用1,依赖于UserLog()这个具体的实现,而调用2,如果对上述代码进行改造,装入和取出分离开,再改变下装入的方式,就可以实现我们调用只要去请求IOC容器就行了。至于这些IOC容器的更深入的使用,大牛的文章或者Castle官网去吧。

         当然依赖注入并不是消除依赖实现以插件方式运行的唯一方法,Service Locator就是可替代的方法之一。这个不了解,暂不发言。

         初步的理解,可能会有很多出入,欢迎大家给指点指点。

  • 相关阅读:
    第一阶段冲刺8
    第一阶段冲刺7
    第一阶段冲刺6
    第一阶段冲刺5
    第一阶段冲刺4
    第一阶段冲刺3
    冲刺阶段二
    典型用户和用户场景
    团队题目需求分析-NABCD
    第二阶段第七天
  • 原文地址:https://www.cnblogs.com/forcertain/p/2101717.html
Copyright © 2011-2022 走看看