参考文章:http://www.yuansir-web.com/2014/03/20/%E7%90%86%E8%A7%A3php-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5laravel-ioc%E5%AE%B9%E5%99%A8/?preview

我们在建一个类时,在类的内部有可能会用到另外一个对象实例举个栗子:

class User{
public function getUser(){
$db = new DB(); // 这里产生了对数据库连接类的依赖
$db->select('select username form user..');
...
}
}

当我们修改了DB这个类时肯定要回来修改User这个类,可以想象DB类肯定不是只用在User类中,一个项目中要有许多类要用到DB类,如果DB类修改了(举个不恰当的例子:DB这个类改名了)那必须要把项目中所有用到db类的类都要作修改。

这个时候可以这样解决

class User{
public function getUser(DB $db){
//$db = new DB(); // 依赖消失
$db->select('select username form user..');
...
}
}

这个时候想调用getUser方法就必须要“注入”$db。

实际中我们的User类肯定不是只会用到getUser这个方法的,还有可能会用到getUsername、getUserAge、getUserSex...等等,难道我们要为每个方法都加一个$db参数吗?当然不可能所以我们再来完善一下这个User类:

class User{
private $db;
//*
public function __construct(DB $db){
$this->db = $db;
}
/*/
public function getDb(DB $db){
$this->db = $db;
}
//*/
public function getUser(){
$this->db->select('select username form user..');
...
}
public function getUserAge(){
$this->db->select('select userage form user..');
...
}
public function getUserSex(){
$this->db->select('select usersex form user..');
...
}
}

可以看到我们可以在构造器和getDb方法中注入$db。

好了,我们已经实现“依赖反转”了!但是!!!假如我们User类还需要其他类呢?举个很不恰当的牵强的栗子:

我们把username放到memcache 中,把userage放到session中,把usersex放到redis中(这。。。很不实际)那我们的类就变成这个样子了

class User{
private $db;
private $mem;
private $redis;
  ...
public function __construct(DB $db , Mem $mem , Redis $redis , Session $session ...... ){
$this->db = $db;
$this->mem = $mem;
$this->redis = $redis;
} public function getUser(){
$this->db->select('select username form user..');
...
}
public function getUserAge(){
$this->mem->get('userage');
...
}
public function getUserSex(){
$this->redis->get('usersex');
...
}
}

要在控制器里放那么多实例。而且如果要使用User类的话还有实例这么多存贮类,不累吗?代码肯定一团糟!

这个时候可以用一个工厂来“完善”一下:

class UserFactory{
public static function getUserObj(){
$db = new DB();
$mem = new Mem();
...
$user = new ($db , $mem , ...);
return $user;
}
}

这样就好看多了,但是!!!然并卵,我们还是要实例化各个存储类(db,mem,redis。。。)

现在该服务容器(IoC)登场了:

class User{
private $IoC;
public function __construct(IoC $IoC){
$this->IoC = $IoC;
} public function getUser(){
$this->IoC->get('db')->select('select username form user..');
...
}
public function getUserAge(){
$this->IoC->get('mem')->get('userage');
...
}
public function getUserSex(){
$this->IoC->get('redis')->get('usersex');
...
}
} $IoC = new IoC();
// 这里使用了闭包函数,$di->set的时候实际上并没有实例化,
// 而是在$di->get()的时候才执行了匿名函数并将对象返回。
$IoC->set('db' , function(){
return new DB(...);
});
$IoC->set('mem' , funciton(){
return new Mem(...);
});
$IoC->set('redis' , funciton(){
return new Redis(...);
});
$user = new User($IoC);

大功告成!!!!!!

DI与IoC就是这么简单。

分享几个链接:

symfony中服务容器:

http://www.cnblogs.com/Seekr/archive/2012/06/19/2554934.html

听 Fabien Potencier 谈Symfony2 之 《What is Dependency Injection ?》

http://www.cnblogs.com/Seekr/archive/2012/06/20/2556463.html

另外还有laravel、struts2、spring有关依赖注入的文章可以自行搜索。

依赖注入(DI)与服务容器(IoC)的更多相关文章

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

    依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...

  2. PHP依赖注入(DI)和控制反转(IoC)详解

    这篇文章主要介绍了PHP依赖注入(DI)和控制反转(IoC)的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程 ...

  3. 话说 依赖注入(DI) or 控制反转(IoC)

    科普:首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些 ...

  4. 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)

    前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...

  5. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  6. PHP 依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI —— Dependency Injection 依赖注入 IoC —— Inversion of Control ...

  7. 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  8. 聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)

    简介 IoC Inversion of Control 控制反转DI Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一种东西,它们是一种设计模式,这种设计模式用来 ...

  9. 如何理解 PHP的依赖注入(DI) 和 控制反转(IoC)

    名词解释: IoC - Inversion of Control 控制反转 DI - Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一个东西,它们是一种设计模式, ...

随机推荐

  1. 8.4.2 Fresco

    Fresco是Facebook公司的黑科技:http://fresco-cn.org/ 真三级缓存,变换后的BItmap(内存),变换前的原始图片(内存),硬盘缓存.在内存管理上做到了极致.对于重度图 ...

  2. C# interface

    我们学习了interface,即接口,其与抽象类有点像,但是他们也有一些区别,比如类不能多重继承但是接口却可以多重继承. 接口只包含方法.委托或事件和属性的签名(接口包含的成员).不能包含字段(因为字 ...

  3. 百度ueditor 实例化 Cannot set property 'innerHTML' of null 完美解决方案

    此时此刻,我正在用博客园推荐的TinyMCE编辑器写这个博客,突然想起最近在项目中使用百度ueditor编辑器中的一些经历.所以记录在此,与大家分享. 不得不说,百度ueditor是一款很好的在线编辑 ...

  4. Cookie与Session的区别-总结很好的文章

    Cookie与Session的区别-总结很好的文章 本文分别对Cookie与Session做一个介绍和总结,并分别对两个知识点进行对比分析,让大家对Cookie和Session有一个更深入的了解,并对 ...

  5. iOS 笔记

    1. 使用断言NSAssert()调试程序错误 NSAssert()只是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续 ...

  6. Mysql创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES)

    MySQL创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES) ,多半是因为存在匿名用户, ...

  7. python 多线程和多进程基本写法

    #coding=utf-8 def aJob(arg): """ 提供给多线程调用 """ import threading t = thr ...

  8. SQLSERVER中如何忽略索引提示

    SQLSERVER中如何忽略索引提示 当我们想让某条查询语句利用某个索引的时候,我们一般会在查询语句里加索引提示,就像这样 当在生产环境里面,由于这个索引提示的原因,优化器一般不会再去考虑其他的索引, ...

  9. 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。

    [TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...

  10. 使用OAuth打造webapi认证服务供自己的客户端使用(二)

    在上一篇”使用OAuth打造webapi认证服务供自己的客户端使用“的文章中我们实现了一个采用了OAuth流程3-密码模式(resource owner password credentials)的W ...