话说 依赖注入(DI) or 控制反转(IoC)

iOS控制反转(IoC)与依赖注入(DI)的实现 背景最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能。Java语言自带的注解特性为IoC和DI带来了极大的方便,要在OC上较好的实现这两个功能,需要一些小小的技巧。控制反转和依赖注入控制反转简单来说,将一个类对象的创建由手动new方式改为从IOC容器内获取,就是一种控制反转,例如我们现在要创建一个Class 阅读详情

原文地址:http://www.thinkphp.cn/topic/12180.html

科普:
首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些力量。

首先先别追究这个设计模式的定义,否则你一定会被说的云里雾里,笔者就是深受其害,百度了N多文章,都是从理论角度来描述,充斥着大量的生涩词汇,要么就是java代码描述的,也生涩。

不管怎么样,总算弄清楚一些了,下面就以php的角度来描述一下依赖注入这个概念。

先假设我们这里有一个类,类里面需要用到数据库连接,按照最最原始的办法,我们可能是这样写这个类的:
  1. class example {
  2.     
  3.     private $_db;
  4.     function __construct(){
  5.         include "./Lib/Db.php";
  6.         $this->_db = new Db("localhost","root","123456","test");
  7.     }
  8.     function getList(){
  9.         $this->_db->query("......");//这里具体sql语句就省略不写了
  10.     }
  11. }
复制代码
过程:
在构造函数里先将数据库类文件include进来;
然后又通过new Db并传入数据库连接信息实例化db类;
之后getList方法就可以通过$this->_db来调用数据库类,实现数据库操作。

看上去我们实现了想要的功能,但是这是一个噩梦的开始,以后example1,example2,example3....越来越多的类需要用到db组件,如果都这么写的话,万一有一天数据库密码改了或者db类发生变化了,岂不是要回头修改所有类文件?
ok,为了解决这个问题,工厂模式出现了,我们创建了一个Factory方法,并通过Factory::getDb()方法来获得db组件的实例:
  1. class Factory {
  2.     public static function getDb(){
  3.         include "./Lib/Db.php";
  4.         return new Db("localhost","root","123456","test");
  5.     }
  6. }
复制代码
sample类变成:
  1. class example {
  2.     
  3.     private $_db;
  4.     function __construct(){
  5.         $this->_db = Factory::getDb();
  6.     }
  7.     function getList(){
  8.         $this->_db->query("......");//这里具体sql语句就省略不写了
  9.     }
  10. }
复制代码
这样就完美了吗?再次想想一下以后example1,example2,example3....所有的类,你都需要在构造函数里通过Factory::getDb();获的一个Db实例,实际上你由原来的直接与Db类的耦合变为了和Factory工厂类的耦合,工厂类只是帮你把数据库连接信息给包装起来了,虽然当数据库信息发生变化时只要修改Factory::getDb()方法就可以了,但是突然有一天工厂方法需要改名,或者getDb方法需要改名,你又怎么办?当然这种需求其实还是很操蛋的,但有时候确实存在这种情况,一种解决方式是:

我们不从example类内部实例化Db组件,我们依靠从外部的 注入,什么意思呢?看下面的例子:
  1. class example {
  2.     private $_db;
  3.     function getList(){
  4.         $this->_db->query("......");//这里具体sql语句就省略不写了
  5.     }
  6.     //从外部注入db连接
  7.     function setDb($connection){
  8.         $this->_db = $connection;
  9.     }
  10. }
  11. //调用
  12. $example = new example();
  13. $example->setDb(Factory::getDb());//注入db连接
  14. $example->getList();
复制代码
这样一来,example类完全与外部类解除耦合了,你可以看到Db类里面已经没有工厂方法或Db类的身影了。我们通过从外部调用example类的setDb方法,将连接实例直接注入进去。这样example完全不用关心db连接怎么生成的了。
这就叫 依赖注入,实现不是在代码内部创建依赖关系,而是让其作为一个参数传递,这使得我们的程序更容易维护,降低程序代码的耦合度,实现一种松耦合。

这还没完,我们再假设example类里面除了db还要用到其他外部类,我们通过:
  1. $example->setDb(Factory::getDb());//注入db连接
  2. $example->setFile(Factory::getFile());//注入文件处理类
  3. $example->setImage(Factory::getImage());//注入Image处理类
  4. ...
复制代码
我们没完没了的写这么多set?累不累?
ok,为了不用每次写这么多行代码,我们又去弄了一个工厂方法:
  1. class Factory {
  2.     public static function getExample(){
  3.         $example = new example();
  4.         $example->setDb(Factory::getDb());//注入db连接
  5.         $example->setFile(Factory::getFile());//注入文件处理类
  6.         $example->setImage(Factory::getImage());//注入Image处理类
  7.         return $expample;
  8.     }
  9. }
复制代码
实例化example时变为:
  1. $example=Factory::getExample();
  2. $example->getList();
复制代码
似乎完美了,但是怎么感觉又回到了上面第一次用工厂方法时的场景?这确实不是一个好的解决方案,所以又提出了一个概念: 容器,又叫做 IoC容器、 DI容器。

我们本来是通过setXXX方法注入各种类,代码很长,方法很多,虽然可以通过一个工厂方法包装,但是还不是那么爽,好吧,我们不用setXXX方法了,这样也就不用工厂方法二次包装了,那么我们还怎么实现依赖注入呢?
这里我们引入一个约定:在example类的构造函数里传入一个名为Di $di的参数,如下:
  1. class example {
  2.     private $_di;
  3.     function __construct(Di &$di){
  4.         $this->_di = $di;
  5.     }
  6.     //通过di容器获取db实例
  7.     function getList(){
  8.         $this->_di->get('db')->query("......");//这里具体sql语句就省略不写了
  9.     }
  10. }
  11. $di = new Di();
  12. $di->set("db",function(){
  13.    return new Db("localhost","root","root","test"); 
  14. });
  15. $example = new example($di);
  16. $example->getList();
复制代码
Di就是IoC容器,所谓容器就是存放我们可能会用到的各种类的实例,我们通过$di->set()设置一个名为db的实例,因为是通过回调函数的方式传入的,所以set的时候并不会立即实例化db类,而是当$di->get('db')的时候才会实例化,同样,在设计di类的时候还可以融入单例模式。
这样我们只要在全局范围内申明一个Di类,将所有需要注入的类放到容器里,然后将容器作为构造函数的参数传入到example,即可在example类里面从容器中获取实例。当然也不一定是构造函数,你也可以用一个 setDi(Di $di)的方法来传入Di容器,总之约定是你制定的,你自己清楚就行。

这样一来依赖注入以及关键的容器概念已经介绍完毕,剩下的就是在实际中使用并理解它吧!

本文如有错误,请务必指出,大家共同学习,共同进步。

转载请注明出处。
阿里云
评论(22) 相关
zhuyuseng 06月04日
不管别人怎么说,个人认为,说得通俗易懂就行。
zstxt1989 04月20日
这篇文章时间太过久远已经无法编辑,文章中那个时候的我对依赖注入的实现理解还是太嫩了,实际上类也不应当依赖$di对象,依赖注入的意思是通过反射分析类所依赖的其他类,从容器中获取相应的对象并自动注入到类里面。
回复 solomon_zjf 04月20日
重新来一发吧。
DSduoduo 03月20日
文章就不评论好坏了。发一下很不错的一篇 https://segmentfault.com/a/1190000002411255 
转发的文章 依赖注入与控制反转讲的思路非常经常,也完成本文的科普。而且对于关键的 实际项目中 用到 依赖注入与控制反转却需要另一个实用的东西,IoC容器。这个容器是第三方 协调注入与反转且更大程度的解耦! 这才是有用的东西。
ynke98328 02月09日
“依赖注入”,个人感觉是一种编程约定,并不是什么技术。或者说是一种编程架构。按照字面上的理解就是:用容器注入的方式减少程序间的依赖。倡导的是一种松耦合的编程习惯。便于代码的维护。感觉大家不必纠结用程序代码的实现。
wanzhende 09月29日
mark一下,学习
skylei 08月19日
天下文章一大抄!
fanyilong 07月17日
  1. IoC(Inversion of Controller) 控制反转(概念)
  2.     DI(Dependency Inject) 依赖注入(IoC概念中的一种类型实现)
  3.         通过依赖声明自动实例化依赖的类(通常通过反射实现)
  4.         Container 容器 
  5.         存储实例化对象 单例的一种实现工具
  6.         ServiceProvider 服务提供者
  7.         一次实例化一批(也可能是一个) 需要使用的类
  8.         并可做一个容器中对象的别名绑定
  9.         Factory 工厂
  10.         一个实例化类的对象 通过上层(框架)实例化
复制代码
声线 2016年05月23日
厉害,,能继续说说DI class吗
qdujunjie 2016年05月20日
楼主解释的很详尽,不知道耦合度到这一步还可不可以再降低?
yxz_blue 2016年05月11日
受益匪浅,很好的文章

马明PHP框架之ThinkPHP项目CMS内容管理系统源码+文档_dichenghao 立即下载

相关推荐

1.PHP框架之ThinkPHP项目CMS内容管理系统-项目设计dichenghao

1.PHP框架之ThinkPHP项目CMS内容管理系统-项目设计

PHP 依赖注入 (设计模式)

首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些力量。 首先先别追究这个设计模式的定义,否则你一定会被说的云里雾里,笔者就是深受其害,百度了N多文章,都是从理论角度来描述,充斥着大量的生涩词汇,要么就是java代码描述的,也生涩。 不管怎么样

wab5168的专栏 1212

php依赖注入demo

设计模式都是一种思想都是 通用的,依赖注入把模块间的耦合性降低了,值得去学习一下。

php设计模式之依赖注入

依赖注入是一种设计模式,用于解耦和管理对象之间的依赖关系。它通过将依赖关系从代码中硬编码的方式改为由外部提供,使得代码更加灵活、可测试和可维护。依赖注入有三种常见的方式:构造函数注入、方法注入和属性注入。

jkzyx123的博客 1792

AI Agent评估:指标、策略与最佳实践

AI智能体正逐渐融入到各个领域,从日常的对话助手到复杂的工作流程自动化,其应用范围不断拓展。然而,确保这些智能体能够可靠、高效地完成任务至关重要,这就使得AI智能体评估成为了人工智能发展过程中不可或缺的一环。本文将深入探讨AI智能体评估的指标、策略以及最佳实践,为读者全面解读这一关键领域。

llm_way的博客 3498

Zemax新手别慌!一文搞懂几何像差:从球差、慧差到色差的实战识别与优化

本文为Zemax新手提供几何像差实战指南,详细解析球差、彗差和色差的识别与优化方法。通过软件操作关键节点和实际项目决策逻辑,帮助光学设计师快速掌握像差诊断与优化技巧,提升光学设计效率。

weixin_42524708的博客 259

php依赖注入的原理是什么

依赖注入(Dependency Injection)是面向对象编程(OOP)中的一种设计模式,用于解耦合和提高代码的可维护性、可测试性。在PHP中,依赖注入的原理是通过外部传递依赖对象(通常是类的实例)到类的内部,而不是在类内部创建这些依赖对象。类的构造函数注入(Constructor Injection): 在依赖注入中,依赖对象通常通过类的构造函数传入。类的构造函数接受依赖对象作为参数,然后在类的内部使用这些依赖对象。这种方式确保了依赖对象在类被实例化时就被传入,避免了在类内部直接创建依赖对象。

weixin_43187635的博客 384

ArcGIS新手必看:用Landsat 8数据计算植被覆盖度的完整流程(附DEM裁剪技巧)

本文为ArcGIS新手提供了使用Landsat 8数据计算植被覆盖度的完整流程指南。详细讲解了从数据预处理、NDVI计算到基于像元二分模型反演植被覆盖度的核心步骤,并重点分享了利用DEM进行精确裁剪的实用技巧,帮助用户高效完成地表信息提取与分析。

weixin_29279047的博客 239

Spring入门使用:IOC控制反转与DI依赖注入详解

本文介绍了Spring框架的核心概念IOC(控制反转)和DI(依赖注入)。IOC将对象控制权交给Spring容器,通过XML配置实现对象管理;DI则通过setter或构造方法注入依赖对象。文章详细演示了Spring的配置步骤、Bean属性设置及依赖注入方式,包括单例/多例作用域配置和引用类型的注入。通过示例代码展示了如何利用Spring简化JavaEE开发,实现对象间的解耦和灵活管理。

先做到 再看见 1362

信息学奥赛一本通高手训练1680:序列

题目 代码 #include<cstdio> #include<iostream> #include<cmath> #define LL long long using namespace std; const LL N = 1400000+7; const LL mod = 1e9+7; int n, t; LL pos[N], sum[N], ans[N]; struct node{ LL ll, rr; }a[N]; int main(){ p

qingfeixueyue的博客 468

对比实验系列:Efficientdet环境配置及训练个人数据集

可以通过下方链接下载Efficientdet源码。

Yayisheng的博客 4586

控制反转IOC和依赖注入DI详解

本文介绍了Spring框架中的控制反转IOC和依赖注入DI,欢迎阅读,共同学习,一起进步。 Spring框架基础参考:深入学习Spring基础 文章目录一.入门程序和IOC简介二.IOC-控制反转三.DI-依赖注入四. IOC和DI五.Spring框架使用(IoC)六.注入类型的三种方式 一.入门程序和IOC简介 依赖注入或控制反转的定义中,调用者不负责被调用者的实例创建工作,该工作由S...

末尾卡片和博主交流学习! 2865

点云中概念:匹配、配准、融合

匹配,是寻找与一幅图相似的图像(不对寻找到的图像做矫正)。 配准,是寻找相似图像但是变形后的图像(需要做一些旋转之类的校正变换)。 融合,是多幅图像连接成一幅大图,视频集成中用的比较多。 1)匹配: 2)配准: 比如由于固定式激光雷达受测量方式的限制和被测物体集合形状的限制,固定的话一次只能扫描被测物体有限范围的点云数据(比如一个面??),这需要在多个视角下进行多次扫描(就是将激光雷达前后左右四个面都扫一下??对的),然而每个视角下得到点云数据都具有独立的坐标系,无法直接进行拼接(拼接就是将四个面

m0_37957160的博客 1万+

Spring中的控制反转和依赖注入(IoC和DI)以及常见面试题

Spring在不同情景下呢有不同的意思。(1)比如说你的项目里面使用到了Spring,那这里的Spring指的是Spring家族包含了各种各样的框架;(2)要是说Spring有什么特点其中一个是IoC那么这里指的就是Spring Core,Spring Framework。(Spring Core 是 Spring Framework 的核心模块,主要负责实现 IoC 和 DI 功能;

change_topic的博客 1936

AI漫剧全套万能提示词合集

今天给大家整理一套已经跑通爆款漫剧的万能提示词库!覆盖:豆包剧本人设词 + 分镜生成词 + 即梦绘图词 + 动态优化词 + 防翻车固定词直接复制粘贴,新手也能做出稳定、高清、统一、有质感的AI漫剧!你是资深短视频漫剧编剧,擅长制作60秒竖屏爆款AI漫剧,请为我创作一集完整漫剧内容。要求:开头3秒高能抓眼,中段有冲突转折,结尾留强悬念钩子,节奏紧凑、适合短视频流量。首先生成固定统一人物人设:包含脸型、五官、发色、发型、穿搭、身材、气质、画风、光影细节,要求足够精细,保证全程角色不变脸。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1909

YOLOv8有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例

大家好!欢迎阅读本专栏。本专栏涵盖了YOLO8中C2f、主干网络、检测头、注意力机制、Neck等多种结构的创新,同时也包括了 YOLO相关的基础知识以及相关项目。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 3万+

什么是IOC(控制反转)、DI(依赖注入)

原文地址(摘要了部分内容):https://blog.youkuaiyun.com/qq_22654611/article/details/52606960/ 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC...

qq_42709262的博客 8万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Spring IoC【控制反转】DI【依赖注入】

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序

很高兴你能看到这里 1820

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

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

PHP依赖注入和控制反转(DI&&IoC) User: Jeremy.Ke Time: 2019/6/25 3:32 1 理论分析 1.1 概念 依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。 (1)依赖注入是从应用程序的角度在描述,可以把依赖注入,即:应用程序依赖容器创建并注入它所需要的外部资源; (2)而控制反转是从容器的角度在描...

jeremy_ke的博客 4271

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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

控制反转( IoC)和依赖注入(DI) tags: 容器 依赖注入 IOC DI 控制反转 引言:如果你看过一些框架的源码或者手册,像是laravel或者tp5之类的,应该会提到容器,依赖注入,控制反转等词汇。或者是某些面试官会问到这类问题。希望这篇文章能让你有所收获。 1.1、IoC(控制反转 Inversion of Control) 简述:控制反转并不是一种技术,而是...

vinter_he 1万+

Spring的控制反转(IoC)与依赖注入(DI)详解

一、概念: **控制反转(Inversion of Control,英文缩写为IoC)****:****是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 2020整理收集的一线互联网公司面试真题(都整理成文档),有很多干货,包含netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,我感觉在面试这块讲的非常清楚:获取面试资料只需:点击这里领取!!!暗号:优快云 控制反转一般分为两种类型,依赖注入(Dependen

a3961401的博客 3002

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

IOC:反转控制权—— 不用自己 new 对象,交给 Spring 容器管; DI:依赖注入—— 容器把你需要的对象,主动送到你手里; 核心价值:解耦—— 类和类之间不再通过 new 硬绑死,后续换实现、改逻辑,不用动调用方代码(比如换 UserService 实现,不用改 UserController)。

m0_63819687的博客 1448

IoC(控制反转)与 DI(依赖注入)解析

控制反转(Inversion of Control, IoC)是一种设计原则,其核心思想是将对象的控制权从代码中移交给外部容器。传统的代码由开发者手动控制对象的创建和管理,而在 IoC 模式下,对象的创建和生命周期由容器管理,程序只需关注逻辑本身。简而言之,IoC 的本质是“谁控制谁,控制什么,何时控制反转”谁控制谁:IoC 容器控制对象。控制什么:控制对象的创建、初始化和依赖关系。何时控制反转:在程序运行时,容器负责注入依赖而不是由代码主动获取依赖。

lzz的博客 1698

IOC 和 DI:控制反转与依赖注入的关系

*控制反转(IoC)**是一种设计原则,它将对象的创建和依赖关系的管理从对象本身转移到外部容器。**依赖注入(DI)**是实现IoC的一种具体方式,通过外部容器将依赖关系注入到对象中。在Spring框架中,IoC和DI是通过Spring容器来实现的,可以通过XML配置、Java配置或注解来配置Bean和依赖关系。Spring Boot进一步简化了IoC和DI的配置,提供了自动配置和组件扫描等功能。

xycxycooo的博客 1361
上一篇: ci qq接口
vm021
博客等级 码龄11年 6粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值