依赖注入(DI)与服务容器(IoC)

参考文章: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有关依赖注入的文章可以自行搜索。

时间: 2024-11-04 19:11:13

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

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

首页 下载 扩展 应用 教程 代码 案例 资讯 讨论 全部 搜索 话说 依赖注入(DI) or 控制反转(IoC) 浏览:3641 发布日期:2014/03/20 分类:技术分享 科普:首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些力量. 首先先别追究这个设计模式的定义,否则你一定会被说的云里雾里,笔者就是深受其害,百度了N多文章,都是从理论角度来描

.NET Core Web API使用依赖注入(DI)进行服务配置一

ASP.NET Core的框架的设计从头到尾都是模块化的,并且遵循良好的软件工程实践.在面向对象的程序设计中,SOLID经受住了时间的考验.ASP.NET Core已经把依赖注入融入了核心框架.不管你自己是否想把依赖注入运用到自己的代码中,ASP.NET Core框架已经把依赖注入当成了一个基本概念. SOLID是 Single responsibility, Open-closed, Liskov substitution, Interface segregation, Dependeny i

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

0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境或专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行.详细的介绍可以阅读上一篇博文:http://www.cnblogs.com/dazhuangtage/p/5672190.html 0X2 什么是控制反转 在解释什么是控

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

要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI -- Dependency Injection 依赖注入 IoC -- Inversion of Control 控制反转 什么是依赖注入 没有你我就活不下去,那么,你就是我的依赖. 说白了就是: 不是我自身的,却是我需要的,都是我所依赖的.一切需要外部提供的,都是需要进行依赖注入的. 依赖注入举例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Boy

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

首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些力量. 首先先别追究这个设计模式的定义,否则你一定会被说的云里雾里,笔者就是深受其害,百度了N多文章,都是从理论角度来描述,充斥着大量的生涩词汇,要么就是java代码描述的,也生涩. 不管怎么样,总算弄清楚一些了,下面就以php的角度来描述一下依赖注入这个概念. 先假设我们这里有一个类,类里面需要用到数据

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

名词解释: IoC - Inversion of Control 控制反转 DI - Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一个东西,它们是一种设计模式,这种设计模式用来减少程序间的耦合 依赖注入是从应用程序的角度在描述,可以把依赖注入,即:应用程序依赖容器创建并注入它所需要的外部资源: 而控制反转是从容器的角度在描述,即:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源. 我们为什么使用依赖注入呢? 使用依赖注入 最重要的一点好

依赖注入(DI)与控制反转(IOC)

DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,Inversion of Control )是一个意思. DI是一种通过接口实现松耦合的设计模式.初学者可能会好奇网上为什么有那么多技术文章对DI这个东西大兴其笔,是因为DI对于基于几乎所有框架下,要高效开发应用程序,它都是开发者必须要有的一个重要的理念,包括MVC开发.它是解耦的一个重要手段. DI模式可分为两个部分.一是移除对组件(上面示例中的LinqValueCalculator)的依赖,二是通过类的构造

spring 依赖注入(DI)与控制反转(IOC)

Spring目前所拥有的功能非常多,常用的DI和MVC已经是开发中的家常便饭,而且使用Spring来管理其它的框架也是习以为常的事情.Spring在项目中的最大作用就是为了解耦,降低项目整体的耦合度,尽可能做到低耦合.Spring的核心就是IOC和AOP.IOC控制反转创建bean对象,通过DI依赖注入来完成bean对象的数据封装. IOC是一种开发思想,DI是一种开发实现 虽然业界经常提到什么IOC,什么DI,其实都是一个意思,只是IOC是Spring提出的设计开发思想,而DI是代码实现方式.

【串线篇】依赖注入DI与控制反转IOC

DI&IOC 在spring框架中DI与IOC说的其实是一回事 一句话:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象. 也就是说我对对象的『依赖』是注入进来的,而和它的构造方式解耦了.构造它这个『控制』操作也交给了第三方,也就是控制反转IOC. 优势:在应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取所需要的资源,在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效率.反转控制的思想完全颠覆了应用程序组件