https://my.oschina.net/u/3529405/blog/1821744

<?php
/**
* 依赖注入 IOC DI
* 参考文章
* https://segmentfault.com/a/1190000002411255
* https://segmentfault.com/a/1190000002424023
*/ /**
* IOC
* 控制反转 Inversion of Control
* 依赖关系的转移
* 依赖抽象而非实践
* 比较实用的注入方式有三种
* Setter injection 使用setter方法
* Constructor injection 使用构造函数
* Property Injection 直接设置属性
*/ // IOC 栗子
// 假设一个储存业务 // 定义接口 业务需求一个数据储存 到rides 或者 mysql 中
interface SaveIO {
public function set ();
}
// 定义两种储存方式 并继承(implements)SaveIO 接口
// rides
class RidesClass implements SaveIO {
public function set () {
echo 'rides_save'.PHP_EOL;
}
}
// mysql
class MysqlClass implements SaveIO {
public function set (){
echo 'mysql_save'.PHP_EOL;
}
} // 高层业务
class Business {
private $myBusiness;
public function __construct ($ioc) {
$this->myBusiness = $ioc;
}
public function save () {
$this->myBusiness->set();
}
// 替换依赖
public function replaceIOC ($ioc) {
$this->myBusiness = $ioc;
}
}
echo 'IOC------'.PHP_EOL;
$bus = new Business(new RidesClass());
$bus->save(); // 输出rides_save // 替换成其他依赖
$bus->replaceIOC(new MysqlClass());
$bus->save(); // 输出 mysql_save /**
* DI
* 依赖注入 Dependency Injection
* 容器自动根据配置,将依赖注入指定对象
* 管理应用程序中的『全局』对象(包括实例化、处理依赖关系)。
* 可以延时加载对象(仅用到时才创建对象)。
* 促进编写可重用、可测试和松耦合的代码。
*/
// 首先需要一个容器
class ConComponent {
protected $_di = array();
// 注册 依赖 让依赖存储在$_di 存储形式 $_di->['服务名称']->Closure
public function register ($name,$service) {
$this->_di[$name] = $service;
} /**
* public function save ($name)
* 高层业务,可以另外拓展一个类,不要放在容器里
* (这里只是一个简易的写法,但是不要这样写)
* 实现 class{
* $构造函数=容器返回依赖
* 高层业务根据需求
* 通过$_di[className]()创建依赖类
* 通过$_di[className]()->实现业务
* }
* @param $name
*/
public function save ($name) {
$this->_di[$name]()->set();
}
}
/*
* 重复利用 RedisClass MysqlClass
* 注册依赖
* */
$component = new ConComponent(); // 创建容器 /*
* 注册依赖
* @param name 依赖的名称
* @param function(){} 是一个闭包(closure)
* 所以只有在我们调用一次 $component->_di[name]
* 才会创建一个依赖对象 实现需时创建
* */
$component->register('RedisClass',function () {
return new RidesClass();
});
$component->register('MysqlClass',function () {
return new MysqlClass();
});
echo 'di----'.PHP_EOL;
$component->save('RedisClass'); // 输出rides_save
$component->save('MysqlClass'); // 输出Mysql_save /**
* AOP
* Aspect-oriented programming
* 面向方面编程
* 无需修改任何一行程序代码,
* 将功能加入至原先的应用程序中,
* 也可以在不修改任何程序的情况下移除
*/

PHP 依赖注入,依赖反转 (IOC-DI)的更多相关文章

  1. C#依赖注入控制反转IOC实现详解

    原文:C#依赖注入控制反转IOC实现详解 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. ...

  2. 控制反转和依赖注入(对IOC,DI理解+案例)

    理解 控制反转说的官方一点就是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其实就是一种设计思想,大概思想就是把设计好的对象交给容器控制,而不是在你内部直接控制. 依赖注入是控制反 ...

  3. Helloworld之Spring依赖注入/控制反转(DI/IoC)版

    Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...

  4. 依赖注入[8]: .NET Core DI框架[服务消费]

    包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.当需要消费某个服务实例的时候,我们只需要指定服务类型调用IServicePr ...

  5. 依赖注入[7]: .NET Core DI框架[服务注册]

    包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.服务注册就是创建出现相应的ServiceDescriptor对象并将其添加到 ...

  6. 依赖注入[6]: .NET Core DI框架[编程体验]

    毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动时构建请求处理管道过程中,以及利用该管道处理每个请求过程中使用到的服务对象均来源于DI容器.该DI容器不仅为A ...

  7. 依赖注入[2]: 基于IoC的设计模式

    正如我们在<控制反转>提到过的,很多人将IoC理解为一种"面向对象的设计模式",实际上IoC自身不仅与面向对象没有必然的联系,它也算不上是一种设计模式.一般来讲,设计模 ...

  8. [ASP.NET Core 3框架揭秘] 依赖注入[2]:IoC模式

    正如我们在<依赖注入:控制反转>提到过的,很多人将IoC理解为一种"面向对象的设计模式",实际上IoC不仅与面向对象没有必然的联系,它自身甚至算不上是一种设计模式.一般 ...

  9. 依赖注入&控制反转

    IoC——Inversion of Control  控制反转DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...

  10. PHP关于依赖注入(控制反转)的解释和例子说明

    PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12)   阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...

随机推荐

  1. JavaScript是如何工作: 深入探索WebSocket和HTTP/2与SSE + 如何选择正确的路径!

    原文:<JavaScript是如何工作: 深入探索 websocket 和HTTP/2与SSE +如何选择正确的路径! 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 文章底部分 ...

  2. SQL查询,关联查询的区别 (LEFT JOIN 、LEFT OUTER JOIN、INNER JOIN)

    ), f2 ) ) ), f2 ) ) ------------------------------------------------ ','a1') ','a2') ','a3') ','a4') ...

  3. element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. BZOJ4916: 神犇和蒟蒻(杜教筛)

    题意 求 $$\sum_{i = 1}^n \mu(i^2)$$ $$\sum_{i = 1}^n \phi(i^2)$$ $n \leqslant 10^9$ Sol zz的我看第一问看了10min ...

  5. cf1132G. Greedy Subsequences(线段树)

    题意 题目链接 Sol 昨天没想到真是有点可惜了. 我们考虑每个点作为最大值的贡献,首先预处理出每个位置\(i\)左边第一个比他大的数\(l\),显然\([l + 1, i]\)内的数的后继要么是\( ...

  6. 华为P20无线投屏到电脑 绝地求生投射电脑

    如今出门在外,必不可少的就是手机,如果没有了手机,每个人都会感觉没有安全感,感觉和世界失去了联系,我们每天每个人都在使用手机,但是作为华为手机用户的你,了解华为P20无线投屏到电脑是怎么操作的吗? 使 ...

  7. Wyn BI的机会在哪里:越靠近消费者的行业,比如零售、文娱和金融,信息化投入越大 ZT

    近日,全球知名信息技术咨询公司IDC在网易云创大会上发布了<2018中国企业数字化发展报告>(下称报告).报告显示,近几年我国数字经济占GDP比重逐年增加,至2017年已经达到32.9%, ...

  8. Python变量和简单数据类型

    变量的命名和使用 在Python中使用变量时 ,需要遵守一定的规则和指南. 变量名只能包含字母‘数字和下划线 变量名不能包含空格,但可以用下划线分割其中单词 不要将Python关键字和函数名用作变量名 ...

  9. <自动化测试方案_2>第二章、自动化测试是什么?(What)

    第二章.自动化测试是什么?(What) 自动化测试是相对于手工测试而言:通过脚本自动去执行测试用例,从而代替人完成测试工作. 自动化测试相对手工测试优缺点 测试方式 优点 缺点 手工测试 1,完整的对 ...

  10. 根据标签中动态获取的值绑定特定的class

    数据有mock数据获取 mock文件: index文件: 引入文件index: 获取数据函数: 根据获取的标签内容给定不同的样式: