本文由 ChatMoney团队出品

在软件开发中,控制反转(Inversion of Control,简称IOC)和依赖注入(Dependency Injection,简称DI)是两种常用的设计模式,它们旨在降低组件间的耦合度,提高代码的可维护性和灵活性。

一、控制反转(IOC)模式

控制反转是将组件间的依赖关系从程序内部提到外部来管理。在传统的程序设计中,我们通常在类内部直接实例化其所依赖的类,这样类与类之间的耦合度较高。例如:

class DbMysql {
public function query(){}
} class Controller {
public $db;
public function __construct() {
$this->db = new DbMysql();
}
public function action() {
$this->db->query();
}
} $c = new Controller();$c->action();

在这个例子中,Controller类对DbMysql类产生了依赖。如果DbMysql类的构造函数发生变化,或者我们需要替换为另一个数据库类(如DbOracle),那么Controller类也需要相应地修改。这种方式使得代码的耦合度较高,不利于维护和扩展。

二、依赖注入(DI)模式

依赖注入是指将组件的依赖通过外部以参数或其他形式注入。通过依赖注入,我们可以将组件的创建过程与使用过程分离,降低耦合度。以下是一个依赖注入的示例:

class Controller {
public $db;
public function __construct($dbMysql) {
$this->db =$dbMysql;
}
public function action() {
$this->db->query();
}
} $db = new DbMysql();$c = new Controller($db);$c->action();

在这个例子中,Controller类不再负责实例化DbMysql,而是通过构造函数将DbMysql的实例作为参数传入。这样,Controller类只需关注如何使用DbMysql类,而无需关心其创建过程。

三、IOC容器实践

虽然依赖注入降低了耦合度,但如果项目中有很多类,手动管理这些依赖关系仍然很繁琐。这时,我们可以使用IOC容器来简化这个过程。

以下是一个简单的IOC容器实现:

class Container {
public $bindings = [];
public function bind($key,$value) {
$this->bindings[$key] = $value;
}
public function make($key) {
$concrete =$this->bindings[$key];
return $concrete();
}
} $app = new Container();
$app->bind('db', function () {
return new DbMysql();
});
$db =$app->make('db');

在这个IOC容器中,我们通过bind方法将类名与闭包函数绑定,然后在需要实例化类时,通过make方法调用闭包函数。

四、结合反射优化IOC容器

为了进一步简化依赖注入过程,我们可以引入PHP的反射机制,让IOC容器自动解析类的依赖关系并注入。以下是结合反射的IOC容器实现:

class Container {
// ...(省略其他代码) public function build($className) {
$reflection = new ReflectionClass($className);
$constructor =$reflection->getConstructor();
if (is_null($constructor)) {
return new $className;
} else {
$params =$constructor->getParameters();
$dependencies = [];
foreach ($params as$param) {
$dependencies[] =$this->make($param->getClass()->name);
}
return $reflection->newInstanceArgs($dependencies);
}
}
} // 使用IOC容器
$app = new Container();$app->bind('SMysql', 'DbMysql');
$app->bind('SRedis', 'DbRedis');$app->bind('controller', 'Controller');
$controller =$app->make('controller');
$controller->action();

在这个例子中,我们定义了接口SMysqlSRedis,以及对应的实现类DbMysqlDbRedisController类依赖于这两个接口。通过IOC容器,我们只需简单地将类名与接口绑定,容器会自动解析依赖关系并注入。

总结:

通过控制反转和依赖注入,我们能够有效地降低代码耦合度,提高代码的可维护性和扩展性。IOC容器进一步简化了依赖注入的过程,使得我们在实际开发中能够更加专注于业务逻辑的实现。

关于我们

本文由ChatMoney团队出品,ChatMoney专注于AI应用落地与变现,我们提供全套、持续更新的AI源码系统与可执行的变现方案,致力于帮助更多人利用AI来变现,欢迎进入ChatMoney获取更多AI变现方案!

深入探讨控制反转(IOC)与依赖注入(DI)模式原理与应用实践的更多相关文章

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

    控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...

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

    理解 IOC  http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例      的http:// ...

  3. iOS控制反转(IoC)与依赖注入(DI)的实现

    背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大 ...

  4. 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。

    轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战   ...

  5. 控制反转IOC与依赖注入DI【转】

    转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...

  6. 控制反转IOC与依赖注入DI - 理论篇

    学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...

  7. 【转载】浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

    原文地址 http://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...

  8. 依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

    原文: https://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...

  9. 20181123_控制反转(IOC)和依赖注入(DI)

    一.   控制反转和依赖注入: 控制反转的前提, 是依赖倒置原则, 系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖 (依赖抽象,而不是细节) 如果要想做到控制反转(IOC), 就必须要使 ...

  10. Spring框架学习笔记(1)——控制反转IOC与依赖注入DI

    Spring框架的主要作用,就是提供了一个容器,使用该容器就可以创建并管理对象.比如说Dao类等,又或者是具有多依赖关系的类(Student类中包含有Teacher类的成员变量) Spring有两个核 ...

随机推荐

  1. 在GNU Hurd中感受Mach微内核的进程通信(IPC)

    什么是GNU Hurd 具体的时间线已经在官方维基页面得到详细描述[0],笔者在此就简单叙述一下.在1983年Richard Stallman开启了GNU项目,目的是创建一个自由的操作系统[1].在接 ...

  2. 探秘Transformer系列之(15)--- 采样和输出

    探秘Transformer系列之(15)--- 采样和输出 目录 探秘Transformer系列之(15)--- 采样和输出 0x00 概述 0x01 Generator 1.1 Linear 1.2 ...

  3. DevOps - DevOps基础概念梳理

    目录 DevOps DevOps的好处与价值 可能的几个关注点 DevOps能力环 DevOps与持续集成.持续交付 一个完整的过程 典型的CICD流水线过程 DevOps黄金思维圈 初见 一些图示 ...

  4. android中大咖:TlistView

    d的android中的Tlistview相当于cxGrid,其开发使用中的主咖地位至高无上. 可是如何高效使用快速实现的需求呢?需要的话补官方的教程 上图: GOODLUCK!

  5. Mybatis常用配置参数

    Mybatis-plus官方配置详细文档:  https://mp.baomidou.com/config/常用配置参数如下: mybatis-plus: # mapper配置文件路径 mapper- ...

  6. 干货分享!MCP 实现原理,小白也能看懂

    不知道大家有没有发现?对于添加到 MCP 服务市场的成千上万个 MCP 服务(而且这个数字每天还在增加),我们可以不写一行代码,轻松实现调用,但背后的原因究竟是啥呢? MCP 虽然用起来很方便,但搞不 ...

  7. 🎀springboot banner介绍及使用

    简介 Banner是指应用程序启动时显示的信息.对于Spring Boot应用来说,默认情况下,当你启动一个 Spring Boot应用时,控制台上会打印出一段由 Spring Boot自带的ASCI ...

  8. 🎀腾讯云nodejs SDK打包体积过大吐槽事件

    简介 2025年2月1日有位开发同学batchor在GitHub上提出了issue(你们是把***打包了吗?)对腾讯云Node.js的SDK打包体积过大进行吐槽(言语偏贴吧风格略显激进),SDK打包体 ...

  9. PC端自动化测试实战教程-2-pywinauto 启动PC端应用程序 - 上篇(详细教程)

    1.简介 经过上一篇的学习.介绍和了解,想必小伙伴或者童鞋们,已经见识到pywinauto的强大了,今天继续介绍pywinauto,上一篇已经可以打开计算器了,这里宏哥在提供其他方法进行打开计算器和非 ...

  10. python,去掉“xa0”和“\r\n”

    爬小说网站,输出内容有时候会出现下图字符 首先,去掉"xa0" s = 'T-shirt\xa0\xa0短袖圆领衫,体恤衫\xa0' out = "".join ...