xiaohuihui
for me

容器和依赖注入

2020-03-29 14:07:03
Word count: 1.4k | Reading time: 4min

PHP容器和依赖注入

1.依赖注入

什么是依赖注入? 依赖注入(DI)是一种设计模式,它可以消除编程代码之间的依赖性,因此可以很容易地管理和测试应用程序。在编程中,依赖注入是一种实现控制反转且用于解决依赖性问题的设计模式。一个依赖关系指的是可被利用的一种对象 。依赖注入是将所依赖的传递给将要使用的从属对象。该服务将会变成客户端状态的一部分并传递服务给客户端,而不允许客户端来建立或寻找服务。依赖注入使我们的编程代码变得松散耦合,易于管理。

在我们使用框架的同时,框架多多少少都用到了依赖注入来处理类与类之间的依赖关系。

Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。

1
2
3
4
5
6
7
8
<?php
class A
{
public function __construct()
{
$b = new B();
}
?>

这样做是不可取的,因为这样的话,A与B就耦合在了一起,也就是说A类无法脱离B类工作。

第二种方法:

1
2
3
4
5
6
7
8
9
10
<?php
class A
{
public function __construct(B $b)
{

}

}
?>

第二种方法不必与B类捆绑在一起,只要传入的类满足A类的需求,也可以是C类,也可以是D类,但是如果A类的依赖较多,参数列表会很长,造成混乱,可读性也会变低 .

第三种方法:

1
2
3
4
5
6
7
8
9
10
<?php
class A
{
public function setB(B $b)
{
$this->b = $b;
}

}
?>

第三种方法就是使用set方式传入,但是当依赖的类增多的时候,我们会创建很多set方法,所以这个时候便用到了我们容器的概念,容器的话也可以理解为对象树,它的作用是来帮我们管理这些依赖.

而采用了容器依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

把有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。目的是实现类的解耦。

2.容器与依赖注入

以下将由thinkphp5.1框架来实现依赖注入,然而thinkphp框架里面本来就用了容器与依赖注入,目前我们实现这个,只是为了便于理解.

  • 在thinkphp框架中,我们访问一个URL的时候,最终都将返回控制器,由控制器里面的方法执行,首先,我在application文件下创建了admin模块,在admin模块下创建了Demo1控制器,在里面创建了getName方法,

    访问的时候也将由一下格式访问:

我们可以通过GET方式将数据传到控制器指定的方法中,但是只能传字符串,数值

  • 当我们要传入一个对象到getName方法中,我们该如何传,我们将用依赖注入:向类中传入对象.

    在application文件夹下建一个common(随意名称)文件夹中建个php文件,例子中为Temp.php文件.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?php
    namespace app\common;

    class Temp
    {
    private $name;
    public function __construct($name='Peter')
    {
    $this->name = $name;
    }

    public function setName($name){
    $this->name = $name;
    }
    public function getName(){
    return '方法是: '.__METHOD__.'属性是:'.$this->name;
    }
    }
    ?>
  • 然后我们返回Demo1控制器,新建getMethod方法,实现依赖注入:向类中注入$temp对象.

以上代码的$temp->setName指调用Temp类的setName方法,并传递参数php中文网.其中的类的实例化已经在括号所进行了.

输出结果如下:

  • 将一个类绑定到容器中:

这样的话,当我们需要的时候,直接把对象取出来用,因为类已经被实例化.

输出:

方法还是那个方法,而$name由我们自定义.

  • 绑定闭包到容器

    闭包:匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何php对象那样传递,不过匿名函数仍然是 匿名函数,因此可以调用,还可以传入参数,匿名函数特别适合作为函数或方法的回调。 理论上讲,闭包和匿名函数是不同的概念,不过,php将其视作相同的概念,所以,我提到闭包时,指的也是匿名函数, 反之亦然。在这理解为匿名函数。

总结:Class Demo1中用到了Class Temp的对象$temp,一般情况下,需要在Class Demo1的代码中显式的new一个Class Temp的对象。采用依赖注入技术之后,Class Demo1的代码只需要定义一个私有的Class Temp对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

< PreviousPost
ajax不执行回调函数的原因
NextPost >
PHP经典设计模式
CATALOG
  1. 1. PHP容器和依赖注入
    1. 1.0.1. 1.依赖注入
    2. 1.0.2. 2.容器与依赖注入