我们再编程的时候都会遇到这样的情况,一个类中需要另一个类的实例化并调用实例化后的方法。
下面我们分别用传统方法和依赖注入来实现上面的情况,看看两者的异同。
//传统方法:高层需要用到低层的实例化
class Gao{
public function useDi(){
$Di = new Di();
$Di->save();
}
}
class Di{
public function save(){
echo "this is Di!";
}
}
//上面我们看到传统方法,如果要用到低层类的实例化,name需要在高层类中对其进行实例化。
但是如果低层类有很多呢?比如下面这样:
class Di1{
public function save(){
echo "this is Di1!";
}
}
class Di2{
public function save(){
echo "this is Di2!";
}
}
class Di3{
public function save(){
echo "this is Di3!";
}
}
那么我们高层类如果要用到所有低层类的实例化,那么我们就需要实例化所有的低层类,如下:
class Gao{
public function useDi(){
$Di = new Di();
$Di->save();
}
public function useDi1(){
$Di = new Di();
$Di->save();
}
public function useDi2(){
$Di = new Di();
$Di->save();
}
public function useDi3(){
$Di = new Di();
$Di->save();
}
}
那么,如果我们再添加低层类,比如Di4、Di5、Di6、Di7,我们也要在高层中对其进行实例化,是不是很麻烦呢?
觉得麻烦就对了,麻烦我们就要去找到不麻烦的方法,所以就引出了我们下面要说到的依赖注入模式。
什么是依赖注入呢?
百度百科里面有讲到,个人觉得说的十分的好,
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。
采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,
而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的
方法、对象被获取时的状态由配置文件(如XML)来指定。
好的,下面我们来通过容器实现依赖注入:
1、首先,制作一个容器类:
class Container{
//定义一个私有属性
private $s = array();
//模式方法,当调用一个不存在的属性时触发。
public function __set($k,$c){
$this->s[$k] = $c;
}
}
2、编写我们的高层类:
class Gao{
public function useDi($obj){
$obj->save();
}
}
3、编写我们的低层类:
class Di{
public function save(){
echo "this is Di!";
}
}
class Di1{
public function save(){
echo "this is Di1!";
}
}
class Di2{
public function save(){
echo "this is Di2!";
}
}
class Di3{
public function save(){
echo "this is Di3!";
}
}
假如我们需要用到低层的Di这个类,那么这个时候我们这样调用;
//实例化容器
$c = new Container();
//调用容器中的Di属性,没有的话就触发set魔术方法(这里我们用到了匿名函数function(){}).
$c->Di = function(){
return new Di();
}
//调用容器中的Gao属性,没有的话就触发set魔术方法(这里我们用到了匿名函数function(){}).
$c->Gao = function($c){
return new Gao($c->Di);
}
//将容器中的属性Gao赋给$res
$res = $c->Gao;
//调用$res中的save方法
$res->save();
想要使用其他的低层类,和上面一样调用就行了。
不知道,大家有没有发现。通过使用容器的依赖注入,我们再增加低层类,并且要在高层中对其进行
调用的时候,高层代码并没有任何改变,唯一的改变就是增加了一个低层类。
依赖注入不是很好理解,我也是看了好久才懂上面的一点皮毛,希望对想要学习依赖注入的朋友有所帮助。