PHP控制反转(IOC)和依赖注入(DI)
「七天自制PHP框架」已经开始连载,谢谢关注和支持!点击这里
先看一个例子:
<?php class A
{
public $b;
public $c;
public function A()
{
//TODO
}
public function Method()
{
$this->b=new B();
$this->c=new C(); $this->b->Method();
$this->c->Method(); //TODO
}
} class B
{
public function B()
{
//TODO
}
public function Method()
{
//TODO
echo 'b';
}
} class C
{
public function C()
{
//TODO
}
public function Method()
{
//TODO
echo 'c';
}
} $a=new A();
$a->Method(); ?>
上面代码,我们很容易理解一句话:
A类依赖B类和C类
也就是说,如果今后开发过程中,要对B类或者C类修改,一旦涉及函数改名,函数参数数量变动,甚至整个类结构的调整,我们也要对A类做出相应的调整,A类的独立性丧失了,这在开发过程中是很不方便的,也就是我们说的“牵一发动全身”,如果两个类是两个人分别写的,矛盾往往就在这个时候产生了。。。
万一真的要改动B类和C类,有没有办法,可以不去改动或者尽量少改动A类的代码呢?这里要用到控制反转。
高层模块不应该依赖于底层模块,两个都应该依赖抽象。
控制反转(IOC)是一种思想,依赖注入(DI)是实施这种思想的方法。
第一种方法叫做:构造器注入(这种方法也不推荐用,但比不用要好)
class A
{
public $b;
public $c;
public function A($b,$c)
{
$this->b=$b;
$this->c=$c;
}
public function Method()
{
$this->b->Method();
$this->c->Method();
}
}
客户端类这样写:
$a=new A(new B(),new C());
$a->Method();
A类的构造器依赖B类和C类,通过构造器的参数传入,至少实现了一点,就是B类对象b和C类对象c的创建都移至了A类外,所以一旦B类和C类发生改动,A类无需做修改,只要在client类里改就可以了
假如有一天,我们需要扩充B类,做两个B类的子类
class B
{
public function B()
{
//TODO
}
public function Method()
{
//TODO
echo 'b';
}
}
class B1 extends B
{
public function B1()
{
//TODO
}
public function Method()
{
echo 'b1';
}
}
class B2 extends B
{
public function B2()
{
//TODO
}
public function Method()
{
echo 'b2';
}
}
也很简单,客户端类这么写:
$a=new A(new B2(),new C());
$a->Method();
所以A类是不用关心B类到底有哪些个子类的,只要在客户端类关心就可以了。
第二种方法叫做:工厂模式注入(推荐使用)
class Factory
{
public function Factory()
{
//TODO
}
public function create($s)
{
switch($s)
{
case 'B':
{
return new B();
break;
}
case 'C':
{
return new C();
break;
}
default:
{
return null;
break;
}
}
}
}
我们A类代码改为:
class A
{
public $b;
public $c;
public function A()
{
//TODO
}
public function Method()
{
$f=new Factory();
$this->b=$f->create('B');
$this->c=$f->create('C'); $this->b->Method();
$this->c->Method(); //TODO
}
}
其实已经解耦了一小部分,至少如果B类和C类的构造函数要是发生变化,比如修改函数参数等,我们只需要改Factory类就可以了。
抽象不应该依赖于细节,细节应该依赖于抽象。
把B类和C类中的方法再抽象出来,做一个接口
interface IMethod
{
public function Method();
}
这样,A类中的$b变量和$c变量就不再是一个具体的变量了,而是一个抽象类型的变量,不到运行那一刻,不知道他们的Method方式是怎么实现的。
class B implements IMethod
{
public function B()
{
//TODO
}
public function Method()
{
//TODO
echo 'b';
}
} class C implements IMethod
{
public function C()
{
//TODO
}
public function Method()
{
//TODO
echo 'c';
}
}
总结几点:
1.我们把A类中的B类对象和C类对象的创建移至A类外
2.原本A类依赖B类和C类,现在变成了A依赖Factory,Factory依赖B和C。
PHP控制反转(IOC)和依赖注入(DI)的更多相关文章
- 控制反转IOC与依赖注入DI
理解 IOC http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例 的http:// ...
- 控制反转(Ioc)和依赖注入(DI)
控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...
- iOS控制反转(IoC)与依赖注入(DI)的实现
背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大 ...
- 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。
轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战 ...
- 控制反转IOC与依赖注入DI【转】
转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...
- 【转载】浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)
原文地址 http://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...
- 控制反转IOC与依赖注入DI - 理论篇
学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...
- 依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)
原文: https://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...
- 20181123_控制反转(IOC)和依赖注入(DI)
一. 控制反转和依赖注入: 控制反转的前提, 是依赖倒置原则, 系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖 (依赖抽象,而不是细节) 如果要想做到控制反转(IOC), 就必须要使 ...
- Spring框架学习笔记(1)——控制反转IOC与依赖注入DI
Spring框架的主要作用,就是提供了一个容器,使用该容器就可以创建并管理对象.比如说Dao类等,又或者是具有多依赖关系的类(Student类中包含有Teacher类的成员变量) Spring有两个核 ...
随机推荐
- YII 1.0 缓存使用
在main.php的组件components中配置设置添加缓存 'cache'=>array( 'class' => 'system.caching.CFileCache' ), 也就是f ...
- redis sets类型及操作
sets类型及操作set是集合,它是string类型的无序集合.通过hash table实现,添加.删除.查找的复杂度都是0(1).对集合我们可以实现取交际.差集并集.通过这些操作我们可以实现SNS中 ...
- ILSpy .NET反编译工具下载地址
官方下载: http://ilspy.net/ 中文版下载地址: http://www.fishlee.net/soft/ilspy_chs/#C-310
- "类型初始值设定项引发异常"
问题出现的原因:在对类中的字段或属性直接赋值的时候出现异常而造成的这个异常. 例如: class MyClass { public static string ConnectionString = G ...
- 深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)
只关注括号内问题的同学,可直接跳转到蓝字部分.(标题起的有点大,其实只讨论一个问题) 两个在React组件上绑定的事件,产生冲突后,使用e.stopPropagation(),阻止冒泡,即可防止事件冲 ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第六章:管理产品图片——多对多关系(上篇)
在这章中,我们将学习如何创建一个管理图片的新实体,如何使用HTML表单上传图片文件,并使用多对多关系将它们和产品关联起来,如何将图片存储在文件系统中.在这章中,我们还会学习更加复杂的异常处理,如何向模 ...
- android: activity切换之效果
Activity是android应用的重要部分;为了提高用户的体验度,加了Activity之间切换的动画效果,现在介绍的一种切换动画: 是什么效果,大家自已动手测试一下便知道: 先看进入的动画: pa ...
- 蓝桥网试题 java 基础练习 十六进制转十进制
---------------------------------------------------------------------------------------- 貌似用int类型不会超 ...
- 源码(06) -- java.util.AbstractList<E>
java.util.AbstractList<E> 源码分析(JDK1.7) ------------------------------------------------------- ...
- asp.net权限认证:OWIN实现OAuth 2.0 之授权码模式(Authorization Code)
asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...