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

首先要解决的两个问题。

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在婚介所进行注册,完了你去表达你需要的依赖,这时候控制权从你的手上变为婚介所的手上,婚介所进行筛选完毕后,把女朋友注入给你,控制权又交到了你的手上,整个过程就是一个典型的依赖注入。

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

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

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
控制反转(Inversion of Control,简称IoC)和依赖注入(Dependency Injection,简称DI)是两个相关的概念,用于解耦和管理对象之间的依赖关系。 控制反转IoC)是一种设计原则,它将对象的创建和管理权从应用程序代码中转移到容器中。传统的程序设计中,对象之间的依赖关系由对象自己创建和管理,而在IoC中,容器负责创建和管理对象,并将它们注入到需要它们的地方。 依赖注入DI)是实现IoC的一种方式。它通过将依赖关系作为参数传递给对象,或者通过使用容器来自动注入依赖关系,来实现对象之间的解耦。依赖注入可以通过构造函数注入、属性注入或者接口注入等方式来实现。 下面是一个简单的示例来说明IoCDI的概念: 假设我们有一个UserService类,它依赖于一个UserRepository类来获取用户数据。在传统的程序设计中,UserService需要自己创建UserRepository对象并管理它的生命周期: ```java public class UserService { private UserRepository userRepository; public UserService() { userRepository = new UserRepository(); } public User getUserById(int id) { return userRepository.getUserById(id); } } ``` 而在使用IoCDI的方式下,我们可以将UserRepository的创建和管理交给容器来处理,UserService只需要声明它所依赖的UserRepository,并通过构造函数或者属性注入的方式接收它: ```java public class UserService { private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User getUserById(int id) { return userRepository.getUserById(id); } } ``` 在这个示例中,UserService不再负责创建UserRepository对象,而是通过构造函数接收一个UserRepository对象。这样,我们可以通过容器来创建UserService,并将一个UserRepository对象注入到它中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值