thinkphp 5.1框架解析(三):容器和依赖注入

  • Post author:
  • Post category:php


之前我们分析了 TP5.1 的错误异常处理机制,顺着代码走我们来看一看 TP5.1的容器概念

在’index.php’中看到了这行代码

// 执行应用并响应
 Container::get('app')->run()->send();

在这里 TP5.1 用到了容器的概念,并实现了依赖注入,控制反转。根据这里我做出了这个分享

在讲容器之前我们先了解软件设计的几个概念



相关知识点

依赖倒置原则(Dependence Inversion Principle, DIP)

依赖倒置原则

总结一点就是 底层类应该依赖于上层类,避免上层类依赖于底层类。

控制反转(Inversion of Control, IoC)

控制反转是实现

依赖倒置原则

的一种策略。它将 底层类 和 上层类之间的交互交给第三方来实现

依赖注入(Dependence Injection, DI)

DI是IoC的一种设计模式,是一种套路,按照DI的套路,就可以实现IoC,就能符合DIP原则。 DI的核心是把类所依赖的单元的实例化过程,放到类的外面去实现。

控制反转容器(IoC Container)

当项目比较大时,依赖关系可能会很复杂。 而 IoC Container 提供了动态地创建、注入依赖单元,映射依赖关系等功能,减少了许多代码量。 TP5.1 设计了一个 think\Container 来实现了 DI Container。

上面讲的是不是抽象?原理我们就不讲了,随便一百度都能百度到。我们就具体讲一讲

依赖注入(DI)



控制反转容器(IOC)



依赖注入

在传统的代码中,往往是面向实现编程,比如下面这段代码

class course
{

    function studyPHP(){
        print __CLASS__."正在学习PHP";
    }
    function studyJAVA(){
        print __CLASS__."正在学习JAVA";
    }
    function studyPython(){
        print __CLASS__."正在学习Python";
    }
}

class xsp{
    private  $name=null;
    public function __construct()
    {
        $this->name = new course();
    }
    public   function getClassmate(){
        return $this->name;
    }
}
$A = (new xsp())->getClassmate();

$A->studyJAVA();

在这里就是只针对实现编程,在这里 上层类就是

xsp

类,底层类就是

course

这个类。

可以看到我们上层类依赖下层类 course 的实现,没有准守我们的 依赖倒置原则。

例如我们 xsp 还想学习 Golang 的课程,那么我们需要改动 course 类的代码

为了提高类的复用性。我们对代码做出更改

class course
{
    private $_course=null;
    public function __construct($course)
    {
        $this->_course=$course;
    }
    public function studyCourse(){
        print "我要学习".$this->_course->getCourseName();
    }
}

class JAVA{
    function getCourseName(){
        return __CLASS__;
    }
}
class Python{
    function getCourseName(){
        return __CLASS__;
    }
}

class xsp{
    public  $name=null;
    public function __construct($course)
    {
        $this->name = new course($course);
    }
}

$JAVA = new JAVA();
$A = (new xsp($JAVA))->name;
$A->studyCourse();

//学习python课程
$python = new Python();
$A = (new xsp($python))->name;
$A->studyCourse();

#浏览器输出
我要学习JAVA我要学习Python

这个代码有效解决了我们 课程与 course 的依赖关系,通过构造函数,实现了一个简单的依赖注入

这就是依赖注入的本质所在。为什么称为注入?从外面把东西打进去,就是注入。什么是外,什么是内? 要解除依赖的类内部就是内,实例化所依赖单元的地方就是外。



DI容器

从上面DI注入方式来看,依赖单元的实例化代码是一个重复、繁琐的过程。 可以想像,一个Web应用的某一组件会依赖于若干单元,这些单元又有可能依赖于更低层级的单元, 从而形成依赖嵌套的情形。那么,这些依赖单元的实例化、注入过程的代码可能会比较长,前后关系也需要特别地注意, 必须将被依赖的放在需要注入依赖的前面进行实例化。 这实在是一件既没技术含量,又吃力不出成果的工作,这类工作是高智商(懒)人群的天敌, 我们是不会去做这么无聊的事情的。(摘自深入理解 YII2.0)



TP5.1中的DI容器

这就是我们要讲的重点了。在TP中DI容器吧所有将来可能会用到的 类 都放在我们的 contariner容器中,以供我们调用,



版权声明:本文为qq_36172443原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。