依赖注入(DI)和控制反转(IOC)

来源:互联网 发布:mac必下的软件 编辑:程序博客网 时间:2024/06/03 15:49

首先要解决的两个问题。

1.什么是控制反转和依赖注入

2.为什么我们需要控制反转和依赖注入

什么是控制反转和依赖注入

控制反转(Inversion of control) 是一种解耦的思想,它顾名思义,就是控制权的转移,比如项目经理让你改需求,这里就发生了控制权的转移,主要有三步:

1.项目经理要求你添加功能 (这时,控制权在项目经理)

2.你接到通知后开始添加功能需求 (控制权在你手上)

3.交付需求成品(控制权又回到了项目经理)

这样白话的说,那在实际应用中是怎样的?

Ioc 和 di在spring中表现的最为核心出色,我们先看一个Java的例子。

比方说我们现在有两个类,A 和 B

A 类需要依赖于B,那我们说B是A的依赖。

class A{  public String getData(){    B b = new B();    return b.data;  }}class B{  public String data = "this is a data";}

如果要需要B的实例属性data,我们就s

class B{  B(String args){    //...  }  public String data = "this is a data";}

那么A这个类就彻底毁了,因为当前对B的创建里并没有参数,那么我们需要再去A里添加上这个参数。

但是或许我们可以不必这样做,我们可以把这个恼火的问题甩给顶层开发,也就是我A类的消费者。我只需这样做即可,改变一下A类的声明

class A{    private B b;    A(B b){        this.b = b;    }    public String getData(){      return this.b.data;    }}

现在我们再次使用A类的时候

A a = new A(new B());

现在,当B类改变构造器参数的时候,我们只需要A类的消费者改变一下A的构造器传值。

比如,现在B类构造函数需要一个字符串作为参数。

A a = new A(new B("this is a string"));

可是现在好像还是不怎么乐观,因为我们仅仅是把责任推给了A类的消费者。

这里仅仅是例子,A类只依赖B,但是在实际开发中,A可能会依赖C、D、E、F…这么多的依赖无疑是给A类的消费者增加工作量,因此,我们需要一个更好的方法来解决这个难题。

我们可以选择工厂设计模式 (factory pattern) 来解决这个难题,我们把解决的事情都交给工厂,现在创建一个工厂,假如A不仅仅依赖于B ,还依赖于C 、D、E

class TempFactory{    public A createA(){        return new A(this.createB(),this.createC(),this.createD(),this.createE());    }    public B createB(){        return new B();    }    public C createC(){        return new C();    }    public D createD(){        return new D();    }    public E createE(){        return new E();    }}

现在定义了一个工厂来统一管理ABCDE的依赖创建,现在也只有5个对象的创建,好像也不算太坏,但是如果我们有一大堆的对象依赖, 工厂设计模式好像就显得力不从心了,接下来DI登场了。

控制反转和依赖注入是对同一件事情的两个说法

为了实现依赖注入,我们需要有一个Injector(注入器)

在以前,我们是这样做的

这里写图片描述

现在我们有了依赖注入,我们只需要把注入依赖都交给注入器来完成,实际上整个过程也完成了一次控制反转,这个我们后面再说。

这里写图片描述

如上图所示,现在我们把A类需要依赖的类都注册进注入器,然后,当A类声明需要它们的时候,注入器就会帮忙注入进来,整个注入的繁琐过程,完完全全不需要我们来管理。

简单说一下这里所发生的控制反转(ioc),原来是A需要B,于是在A中创建B的实例,这里A是主导者,控制权在A上,中间构建了一个注入器,这时,当A需要B的时候,注入器会直接注入进来,这个操作的控制权在注入器上,因为是注入器直接注入的,而不是A主动去创建的,这里A是被动,Injector(注入器)是主动,注入完毕后,控制权又交到了A的手上。

还有一个比较经典的结婚的例子,比如,你年过30,还是一个苦逼的程序员,被生活所迫,需要找一个女朋友,但是你又嫌麻烦,于是你找到了婚介所,你提出你的各种要求,之后你就什么都不用管了,然后婚介所帮你筛选,筛选完毕后,婚介所会通知你过来见面,之后的事情你又可以选择结婚还是不结婚,从Ioc的角度来看,婚介所就是一个注入器,而女朋友是你的依赖,各式各样的woman在婚介所进行注册,完了你去表达你需要的依赖,这时候控制权从你的手上变为婚介所的手上,婚介所进行筛选完毕后,把女朋友注入给你,控制权又交到了你的手上,整个过程就是一个典型的依赖注入。

为什么我们需要控制反转和依赖注入

我觉得上面的例子已经说的很清楚了,因为我们的程序需要的是一种低耦合的设计理念,有了依赖注入和控制反转,我们才能专注于业务逻辑,把这些繁琐的依赖管理交给注入器来完成,并且在整个过程中,耦合性大大的降低。

原创粉丝点击