加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 04:46:29 所属栏目:百科 来源:网络整理
导读:参考文章: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 functi

参考文章: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类的类都要作修改。

这个时候可以这样解决

function getUser(DB $db){
        //$db = new DB(); // 依赖消失
        
    }
}

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

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

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


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

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

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

$mem$redis;
  ...
$db,Mem $mem,Redis $redis , Session $session ...... ; $this->mem = $this->redis = $redis; } $this->mem->get('userage'$this->redis->get('usersex' } }

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

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

 UserFactory{
    static  getUserObj(){
         DB();
        $mem =  Mem();
        ...
        $user = new ();
        return $user;
    }
}

?

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

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

$IoCfunction __construct(IoC $this->IoC = $this->IoC->get('db')->select('select username form user..'$this->IoC->get('mem')->get('userage'$this->IoC->get('redis')->get('usersex'
    }
}

$IoC =  IoC();
 这里使用了闭包函数,$di->set的时候实际上并没有实例化,
// 而是在$di->get()的时候才执行了匿名函数并将对象返回。
$IoC->set('db',(){
    return new DB(...);
});
$IoC->set('mem',1)"> funciton(){
    new Mem(...$IoC->set('redis',1)">new Redis(...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有关依赖注入的文章可以自行搜索。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读