最近在看一些文章的时候,无心间看到别人分享的关于依赖注入和控制反转的最通俗的解释,在此记一笔php
首先要知道,IOC不是一种技术,只是一种编程思想,它能指导咱们如何设计出松耦合、更优良的程序。咱们日常开发一个应用程序,都是由咱们在类内部主动建立依赖对象,从而致使类与类之间高耦合,对后期的扩展性和调试维护都是多少带来不便,而提出了IOC容器思想后,咱们在应用层开发时,所须要依赖的类的建立和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,因此对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得很是灵活。数据库
-----编程
网上有一个通俗的解释是这样的,很是便于记忆:app
1.1 首先想说说IOC(Inversion of Control,控制反转),这是什么意思呢,举个简单的例子,咱们是如何找女友的?常见的状况是,咱们处处去看哪里有长得漂亮身材又好的×××姐,而后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,而后嘿嘿……这个过程是复杂深奥的,咱们必须本身设计和面对每一个环节。传统的程序开发也是如此,在一个对象中,若是要使用另外的对象,就必须获得它(本身new一个,或者从JNDI中查询一个),使用完以后还要将对象销毁(好比Connection等),对象始终会和其余的接口或类藕合起来。ide
那么IOC是如何作的呢?有点像经过婚介找女友,在我和女友之间引入了一个第三者:婚姻介绍所。婚介管理了不少男男女女的资料,我能够向婚介提出一个列表,告诉它我想找个什么样的女友,好比长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,而后婚介就会按照咱们的要求,提供一个mm,咱们只须要去和她谈恋爱、结婚就好了。简单明了,若是婚介给咱们的人选不符合要求,咱们就会抛出异常。整个过程再也不由我本身控制,而是有婚介这样一个相似容器的机构来控制。而对于IOC的概念,就是全部的类的建立、销毁都由 IOC容器来控制,也就是说控制对象生存周期的再也不是引用它的对象,而是IOC容器。对于某个具体的对象而言,之前是它控制其余对象,如今是全部对象都被IOC容器控制,因此这叫控制反转。svg
2.二、DI(依赖注入)测试
IOC的一个重点是在系统运行中,动态的向某个对象提供它所须要的其余对象。这一点是经过DI(Dependency Injection,依赖注入)来实现的。好比对象A须要操做数据库,之前咱们老是要在A中本身编写代码来得到一个Connection对象,有了 IOC容器咱们就只须要告诉容器,A中须要一个Connection,至于这个Connection怎么构造,什么时候构造,A不须要知道。在系统运行时,容器会在适当的时候制造一个Connection,而后像打针同样,注射到A当中,这样就完成了对各个对象之间关系的控制。A须要依赖 Connection才能正常运行,而这个Connection是由容器注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 、php等都引入了一个重要机制,即反射(reflection),它容许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性this
因此控制反转IOC(Inversion of Control)是说建立对象的控制权进行转移,之前建立对象的主动权和建立时机是由本身把控的,而如今这种权力转移到第三方,好比转移交给了IOC容器,它就是一个专门用来建立对象的工厂,你要什么对象,它就给你什么对象,有了 IOC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IOC容器了,经过IOC容器来创建它们之间的关系。url
总结:控制的什么被反转了?就是:得到依赖对象的方式反转了。
spa
下面列举一个简单的IOC/DI示例,进一步掌握这个概念究竟是个什么鬼!
代码示意:
代码示意:
<?php /** * 没有IoC/DI的时候,常规的A类使用C类的示例 */ /** * Class C */ class C { public function say() { echo 'hello'; } } /** * Class A */ class A { private $c; public function __construct() { $this->c = new C(); // 实例化建立C类 } public function sayC() { echo $this->c->say(); // 调用C类中的方法 } } $a = new a(); $a->sayC();
当有了IoC/DI的容器后,A类再也不主动去建立C了,以下图所示:
而是被动等待,等待IoC/DI的容器获取一个C的实例,而后反向的注入到A类中,以下图所示:
代码示意:
<?php/** * 当有了IoC/DI的容器后,a类依赖c实例注入的示例 *//** * Class c */class c{ public function say() { echo 'hello'; } }/** * Class a */class a{ private $c; public function setC(C $c) { $this->c = $c; // 实例化建立C类 } public function sayC() { echo $this->c->say(); // 调用C类中的方法 } } $c = new C(); $a = new a(); $a->setC($c); $a->sayC();