博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
依赖注入(DI)与服务容器(IoC)
阅读量:7116 次
发布时间:2019-06-28

本文共 3094 字,大约阅读时间需要 10 分钟。

参考文章: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中服务容器:

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

转载于:https://www.cnblogs.com/orlion/p/4797422.html

你可能感兴趣的文章
Windows 8 新启动方式:混合启动(Hybrid Boot)
查看>>
*.manifest 文件
查看>>
要在jsp界面上显示一行三个控件
查看>>
我的linux学习之路-文件的创建于删除
查看>>
Linux日志分析
查看>>
ORA-00600: internal error code, arguments: [kcratr_nab_less_than_odr]
查看>>
发布/订阅模式
查看>>
RHCE证书的获得过程--1
查看>>
Java (基础自总结)
查看>>
eyoucms uihtml 带html富文本可视化标签
查看>>
SAMBA服务的搭建和访问
查看>>
nginx+webdav
查看>>
Oracle排错工具oerr
查看>>
JSP中出现According to TLD or attribute directive i...
查看>>
css !important用法CSS样式使用优先级判断
查看>>
教你如何让文件“在线对其隐身”
查看>>
如何编写高质量的javascript代码
查看>>
修改DNS大幅提高OS X Mavericks(5.29G)升级下载速度(4.1M/s)
查看>>
浅谈微信三级分销系统的漏洞
查看>>
linux系统目录详解
查看>>