当前位置: 首页 > news >正文

控制反转(IOC)与依赖注入(DI)模式解析及实践

本文由 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 $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');

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

总结:

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

关于我们

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

相关文章:

  • IAP程序升级 与 电脑BIOS 的关系
  • hashmap底层原理(数据结构 put原理 get原理 remove原理)
  • 【RunAsTool】解锁Windows权限:让管理员权限触手可及
  • 2023/8/7 英语每日一段
  • 智能编程新纪元:腾讯AI代码助手的高效编程体验
  • 【初阶数据结构题目】14.随机链表的复制
  • PHP最新可用获取QQ昵称API接口源码_非第三方
  • python语言day3 元组、字典、类型转换
  • Spring Boot相关知识
  • 自动化专业英语
  • 【Oracle EBS R12】第二章 P2P O2C cycle(英文版)
  • 案例开发-日程管理2第一期(超详细教程、配备图文和源代码注释,没学过也能看懂)
  • 基于腾讯云 AI 代码助手的Web端宝可梦图鉴实践记录
  • springboot的拦截器,监听器,过滤器,servlet的使用(三大组件)
  • Arduino教程(1)
  • JS 中的深拷贝与浅拷贝
  • Android Studio:GIT提交项目到远程仓库
  • ESLint简单操作
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • MYSQL 的 IF 函数
  • Python学习之路13-记分
  • Spring框架之我见(三)——IOC、AOP
  • 分享一份非常强势的Android面试题
  • 关于List、List?、ListObject的区别
  • 欢迎参加第二届中国游戏开发者大会
  • 基于webpack 的 vue 多页架构
  • 警报:线上事故之CountDownLatch的威力
  • 前端设计模式
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用Gradle第一次构建Java程序
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 学习笔记TF060:图像语音结合,看图说话
  • 译自由幺半群
  • 数据库巡检项
  • (C#)一个最简单的链表类
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (Ruby)Ubuntu12.04安装Rails环境
  • (超详细)语音信号处理之特征提取
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计高校学生选课系统
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (转)linux 命令大全
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET 4.0中的泛型协变和反变
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .Net 8.0 新的变化
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net MVC中使用angularJs刷新页面数据列表
  • .netcore如何运行环境安装到Linux服务器
  • .NET委托:一个关于C#的睡前故事