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

tags: 容器 依赖注入 IOC DI 控制反转


引言:如果你看过一些框架的源码或者手册,像是laravel或者tp5之类的,应该会提到容器,依赖注入,控制反转等词汇。或者是某些面试官会问到这类问题。希望这篇文章能让你有所收获。

1.1、IoC(控制反转 Inversion of Control)

简述:控制反转并不是一种技术,而是一种设计思想。通过控制反转容器(以后称容器),改变了原本某些对象运行时依赖其他对象资源时需要自己进行获取(比如通过new ClassName),所造成的对象之间的强耦合(耦合的概念如果不理解,可以先去了解一下。)。

  所谓IoC,对于程序来说,就是构造了一个容器,比如在tp5中,这个容器叫Container,此容器来负责控制对象和对象间的关系。在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个),这样的话一个对象A和另一个对象B之间就有了很强的联系(也就是强耦合)。这种耦合体现在如果被依赖的资源类初始化的时候(也可能是其他时候)传入的参数变化了,你要修改两个类的代码,举例说明:
  
你本来用的是php本身的session机制,现在想改成也支持redis,并在初始化的时候增加一个参数来控制。这个时候你不止需要去修改类Session类的代码,还要去修改类A的代码。部分代码如下

//原代码
class Session{function __construct(){//balabala}
}class A{protected $driver;function __construct(){$this->driver = new Session();}
}//需要增加一种redis方式后修改为
class Session{protected $driver;function __construct(string $driver=''){if($driver === ''){//balabala}else if($driver === 'redis'){//增加了一种模式//balabala}else{//balabala}}
}class A{protected $driver;function __construct(){$this->driver = new Session('redis');//我想使用redis了}
}

可以看到,不止我们修改了B的代码,还要去修改A的代码,这样如果依赖关系多起来的话,每次修改A依赖的对象,可能要处理A中很多条代码。会造成对象之间的强耦合。所以我们可以把A需要的东西,在A之前就创建出来,并通过构造函数参数传递给A。代码如下

 class A{protected $driver;function __construct(A $a){//我想使用redis了}
}$driver = new Session('redis');//我想使用redis了
$a = new A($driver)   

这种方法下更改A依赖的所有对象都通过构造方法或者其他方法的形式给A,这些对象本身机制更改的时候就无需修改A的代码了。但是每次自己使用A的时候都去看看A需要些什么在前面都new一遍,感觉上很low啊,不如我们搞一个管家(容器),如果发现你需要什么,管家就给你什么。这样所依赖的类的创建都由容器来控制,也就是说控制对象创建的不再是引用它的对象,而是容器。对于某个具体的对象而言,以前是它控制其他对象,需要什么自己处理,现在是所有对象都被容器控制,所以控制反转是一种控制权的转移。

1.2、DI(依赖注入 Dependency Injection Container)

  IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入,或者叫依赖注入容器)来实现的。比如还是上面的例子,对象A需要操作Session,以前我们总是要在A中自己编写代码来获得一个Session对象,有了 容器这个管家我们就只需要告诉容器,A中需要一个Session对象,至于这个Session对象怎么构造,何时构造,A不需要知道。在系统运行时,容器会在适当的时候制造一个Session,通过构造方法注射到A当中,这样就完成了对各个对象之间关系的控制,而且这种关系是松耦合的。
  A需要依赖 Session才能正常运行,而这个Session是由容器注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? php有一个高级特性是反射(reflection),原理这里大概说一下,

反射可以在php运行中,提取出关于类、方法、属性、参数,注释等的详细信息,并可以动态的调用方法和类等。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。

反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,容器就是通过反射来实现注入的。

总结:
控制反转是说创建对象的控制权进行转移,由原来的资源需求方,转移到了容器,依赖注入是说本来是资源需求方依赖资源,现在资源需求方依赖于容器对资源的注入,可以看出来依赖注入和控制反转说的其实是一个事情。

顺便提一句,目前很多框架中都离不开反射功能。容器是一个典型的例子,容器在laravel和tp5中都是核心功能之一。

希望大家多评论交流,互相学习

控制反转( IoC)和依赖注入(DI)相关推荐

  1. java-12:spring MVC - 控制反转IOC,依赖注入DI

    学习spring框架之前,先理解几个概念: 1.第一部分:依赖倒置原则 2.第二部分:控制反转,控制反转容器(实例) 3.第三部分:控制反转,控制反转容器(全面理解,面试题) 综合性理解:控制反转(I ...

  2. 依赖倒置(DIP),控制反转(IoC)与依赖注入(DI)

    DIP,IoC与DI概念解析 依赖倒置 DIP(Dependency Inversion Principle) DIP的两大原则: 1.高层模块不应该依赖于低层模块,二者都应该依赖于抽象. 2.抽象不 ...

  3. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 "Inversion of Control".依赖注入DI, 全称 "Dependency Injection". 面向的问题:软件开发 ...

  4. 控制反转IOC与依赖注入DI

    为什么80%的码农都做不了架构师?>>>    1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最 ...

  5. 控制反转(IoC)与依赖注入(DI)详解

    文章目录 什么是控制反转(IoC) 控制反转(IoC)有什么作用 控制反转(IoC)是怎么分类的 依赖注入 接口注入 Setter方法注入 构造器注入 依赖查找 上下文依赖查找(Contextuali ...

  6. 控制反转IOC、依赖注入DI的详细说明与举例

    文章目录 引入 IOC介绍 IOC的实现 通过构造函数注入依赖 通过 setter 设值方法注入依赖 依赖注入容器 IOC优缺点 优点 缺点 阅读时忽略语言差异,参考了很多其他博主内容,参考博文在最后 ...

  7. Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)

    目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 ...

  8. 控制反转 IOC 与依赖注入 DI

    引言 简单总结和巩固一下spring的核心原理--IOC和DI的概念,为什么IOC要叫控制反转?IOC和DI的关系是怎样的? 一.IOC 控制反转 初学者可能很好奇,为什么spring framewo ...

  9. [教程]控制反转(IoC)与依赖注入(DI)

    来源: http://zhangjunhd.blog.51cto.com/113473/126530/ 挺简单的,说的也很清楚 ※IoC/DI 依赖Java的反射机制 1.控制反转(Inversion ...

  10. (转载)控制反转(IoC)与依赖注入(DI)

    http://zhangjunhd.blog.51cto.com/113473/126530/ 转载于:https://www.cnblogs.com/eecs2016/articles/741709 ...

最新文章

  1. 计算机教育中缺失的一课 · the missing semester of your cs education
  2. python编程爱心-如何用python画爱心
  3. vue单选,多选,多选的内容显示在页面可删除
  4. 修改Linux终端命令行字体颜色(对比明显,超炫酷)
  5. 升级bios_华硕B350PLUS升级BIOS更换AMD 3900X步骤
  6. Kafka : FileNotFoundException索引文件丢失 xxx.index (No such file or directory)
  7. mysql 怎么查询慢sql语句_如何优化MySQL中查询慢的SQL语句啊?
  8. java 获取叶子节点_java – 如何获取树的所有叶节点?
  9. hdu--1073--字符串处理
  10. findwindow\sendmessage向第三方软件发送消息演示
  11. c语言程序设计运动的小球,课程设计--运动的小球(15页)-原创力文档
  12. python提取停用词_python文本处理 数据挖掘 停用词检索
  13. [02]从零开始学电子技术丛书-自学电子的同学看过来
  14. uniapp唤醒手机地图app
  15. Apache与Nginx虚拟机的三种访问+非简单请求+跨域知识点整理
  16. html表格与CSS控制表格样式
  17. Tomcat 解决“At least one JAR was scanned for TLDs yet contained no TLDs”问题
  18. Freshman的插入排序实现
  19. H3C路由器静态NAT_路由器多WAN口方式解决访问不同专线接入的服务器
  20. 8字磁力计较准的原理

热门文章

  1. 小程序登录/注册页面设计
  2. Hadoop学习系列之Hadoop、Spark学习路线(很值得推荐)
  3. 禾穗HERS | 对不起,你太美国了
  4. java程序中hive数据推送es_Hive表数据同步到es
  5. 从渣渣辉到送你一只鲲 游戏买量高成本僵局如何破?!
  6. python给excel添加超链接_怎样使用python在excel文件中设置超链接
  7. 0.059美元/kWh!印度750MW太阳能项目以创纪录低价招标
  8. 耗时一周时间,我构建了基于知识图谱的医生推荐系统(附完整版 Python 源码)
  9. gis插入的文本怎么搞成两行_办公小技巧:Powerpoint文本框的另类应用
  10. python+jQuery 实现图片颜色比重分析