• IOC原理


    =============================================

    博客原文地址:http://ihongqiqu.com/blog/2014/10/19/inversion-of-control/

    =========================================================

    IoC(Inversion Of Control),直观地讲,就是容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。

    在我们的程序中,要实现某个功能,我们都会用到两个或两个以上的类来协同完成,那么在一个类中,我们就会要有它的合作类的引用,也就是说这个类依赖于别的类,这个合作类的获取,也就是依赖获取的方式主要有三种。

    下面通过一个生动形象的例子介绍控制反转。比如,一个女孩希望找到合适的男朋友,如下图所示,可以有3种方式,即青梅竹马、亲友介绍、父母包办。

    ioc_pic_6_2

    第一种 青梅竹马,也就是自己生成

    此方式比较简单,代码和图示如下:

    1
    2
    3
    4
    5
    
    public class Girl {
      void kiss(){
        Boy boy = new Boy();
      }
    }
    

    ioc_pic_6_3

    第一种方法存在如下问题:

    • 1.Girl类依赖于Boy类,如果Boy类未完成,则编译都不能通过。
    • 2.不能更改,想换Boy的时候,无法进行修改。
    • 3.很难共享,只能自己用。
    • 4.Girl要对Boy的生命周期负责,两个类耦合在了一起。

    第二种 亲友介绍,也就是通过中介得到

    此方法实现代码和图示如下:

    1
    2
    3
    4
    5
    
    public class Girl {
      void kiss(){
        Boy boy = BoyFactory.createBoy();
      }
    }
    

    ioc_pic_6_4

    第二种方法通过使用工程类,间接得到需要的对象。存在如下问题:

    • 1.每个子类的生成的代码都写死在工厂类里面了,如果要换个子类,则必须更改工厂类中的方法
    • 2.面向接口编程,一般都会使用工厂类,一般每个接口都会对于一个工程类,当项目非常大的时候,则会有非常多的工厂类

    第三种 父母包办,也就是直接被注入

    此种方法实现代码和图示如下:

    1
    2
    3
    4
    5
    6
    7
    
    public class Girl {
      void kiss(Boy boy){
        // kiss boy
        boy.kiss();
      }
    
    }
    

    ioc_pic_6_5

    第三种方法只需要在外部传入一个现成的对象给方法调用,不同的实现传入不同的对象即可。




    哪一种为控制反转IoC呢?虽然在现实生活中我们都希望青梅竹马,但在现实世界里,选择的却是父母包办,它就是控制反转,而这里具有控制力的父母,就是所谓的容器概念。

    典型的IOC可以如下图所示。

    ioc_pic_6_6

    IOC可以通过以下3种方式实现:

    第一种 接口注入

    这种方式要求我们自己定义的组建类必须实现容器给定的一个接口,然后容器通过这个接口,为我们的组建类注入所依赖的类 缺点:容器对组建的侵入性会很强,实现的组建只能给此容器用了,移植性不强

    第二种 Setter注入

    在容器中,通过调用对象的setter()方法,将该对象的依赖传递到类当中

    第三种 构造器注入

    通过使用构造器,在类初始化的时候,传入对象的依赖

    如果是这样的话,那么我们仅仅只是完成了一些基于依赖倒转的代码重构工作而已,并没有真正的体现系统的动态性。最大程度的将两个类之间的依赖降低,实现解耦合,我们可以开发基于配置的程序。

    IoC核心理念:

    • 1.在类当中不创建对象,在代码中不直接与对象和服务连接
    • 2.在配置文件中描述创建对象的方式,以及各个组件之间的联系
    • 3.外部容器通过解析配置文件,通过反射来将这些联系在一起

    The Hollywood principle:Don’t call us,we’ll call you. 即,所有组件都是被动的、不主动联系(调用)外部代码, 要等着外部代码的调用————所有的组件的初始化和相互调用都由容器负责实现。 简单的说,就是整个程序之间的关系,都由容器来控制:将程序的控制权反转给容器,就是所谓的反转。

    参考文献地址:

    =================================================

    博客原文地址:http://ihongqiqu.com/blog/2014/10/19/inversion-of-control/

    =================================================

     

  • 相关阅读:
    pytest05-参数化
    pytest04-conftest配置文件
    pytest03-fixture
    pytest02-setup和teardown
    SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为 static ,必须加锁,或者使用 DateUtils 工具类
    线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式
    线程资源最好通过线程池提供
    获取单例对象需要保证线程安全,其中的方法也要保证线程安全
    高度注意 Map 类集合 K / V 能不能存储 null 值的情况,如下表格
    使用 entrySet 遍历 Map 类集合 KV ,而不是 keySet 方式进行遍历的好处
  • 原文地址:https://www.cnblogs.com/jingle1267/p/4068006.html
Copyright © 2020-2023  润新知