本文由 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. Oracle临时表会随另外一个表的创建自动提交并清空

    创建一个临时表,用它导入一些数据 用这个临时表生成另外一个表,用create table ... 但生成的这表总是空的. 原来create table 前会进行提交commit, 而临时表在commi ...

  2. 多态的前提--java进阶day02

    1.多态的前提条件 第一点和第二点都很好理解,第三点父类引用指向子类对象是什么意思?以下图进行讲解 我们以前的写法,如下图,叫做子类引用指向子类 那父类引用呢?就是把左边换成父类Animal即可 因为 ...

  3. 【JDBC第2章】获取数据库连接

    第2章:获取数据库连接 2.1 要素一:Driver接口实现类 2.1.1 Driver接口介绍 java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口.这个接口是提供给数据库厂 ...

  4. 【JVM之内存与垃圾回收篇】本地方法栈

    本地方法栈 Java 虚拟机栈于管理 Java 方法的调用,而本地方法栈用于管理本地方法的调用. 本地方法栈,也是线程私有的. 允许被实现成固定或者是可动态扩展的内存大小.(在内存溢出方面是相同的) ...

  5. 【Ubuntu】在Ubuntu上安装微信

    [Ubuntu]在Ubuntu上安装微信 零.说明 微信官网最近发布了Linux的测试版本,实际使用下来与Windows版本相差不多,本文介绍如何在Ubuntu(Debian系)上安装Linux版本的 ...

  6. 调用 restful的api的方法

    var // myurl : string; tmpstr : String;// string; RespData :TStringStream; sendData : TStringList; j ...

  7. SSL测试证书

    1. tomcat 1.1 生成 keytool -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore -validity 365 过 ...

  8. spring cloud alibaba的小坑:Caused by: com.alibaba.nacos.api.exception.NacosException: endpoint is blank报错问题,

    一.是因为加添spring cloud alibaba配置中心依赖和bootstrap.xml又不使用的问题

  9. python之request请求后响应的数据从中获取指定值

    request请求后响应的数据为字典类型,从中获取指定值 如上图,需要获取Code的值,或者Msg的值 首先把response通过内置json解码器解码输出 response =  response. ...

  10. Sentinel源码—8.限流算法和设计模式总结

    大纲 1.关于限流的概述 2.高并发下的四大限流算法原理及实现 3.Sentinel使用的设计模式总结 1.关于限流的概述 保护高并发系统的三把利器:缓存.降级和限流.限流就是通过限制请求的流量以达到 ...