首页  >  文章  >  php教程  >  Laravel 依赖注入思想

Laravel 依赖注入思想

高洛峰
高洛峰原创
2016-11-21 16:23:561557浏览

依赖注入

依赖注入是个花俏的名词,事实上是指:类的依赖通过构造器或在某些情况下通过「setter」方法「注入」。先看一段 Laravel 控制器里的代码实例:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Users\Repository as UserRepository;

class UserController extends Controller
{
    /**
     * 用户 Repository 的实例。
     */
    protected $users;

    /**
     * 创建一个新的控制器实例。
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

    /**
     * 显示指定 ID 的用户。
     *
     * @param  int  $id
     * @return View
     */
    public function show($id)
    {
        $user_info = $this->users->find($id);
        return view(&#39;user&#39;, [&#39;user_info&#39; => $user_info]);
    }
}

Laravel 通过服务容器来管理类依赖并进行依赖注入。如果使用一个接口作为函数参数的类型提示,这个时候就需要将指定的实现绑定到接口上面:

interface EventPusher {
    public function send($data);
}
class RedisEventPusher implements EventPusher {
    public function send($data) {
        //
    }
}
$this->app->bind(&#39;App\Contracts\EventPusher&#39;, &#39;App\Services\RedisEventPusher&#39;);
use App\Contracts\EventPusher;

/**
 * 创建一个新的类实例。
 *
 * @param  EventPusher  $pusher
 * @return void
 */
public function __construct(EventPusher $pusher)
{
    $this->pusher = $pusher;
}

这个就是所谓的面向接口编程,接口可以理解为一个规范、一个约束。高层模块不直接依赖于低层模块,它们都应该依赖于抽象(指接口)。

使用依赖注入,最重要的一点好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

控制反转

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则。其中**最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

t0128f824aa7ed65fdd.png

<?php
/**
 * 没有IoC/DI的时候,常规的A类使用C类的示例
 */

/**
 * Class c
 */
class c
{
    public function say()
    {
        echo &#39;hello&#39;;
    }
}

/**
 * Class a
 */
class a
{
    private $c;
    public function __construct()
    {
        $this->c = new C(); // 实例化创建C类
    }

    public function sayC()
    {
        echo $this->c->say(); // 调用C类中的方法
    }
}

$a = new a();
$a->sayC();

当有了IoC/DI的容器后,A类不再主动去创建C了,如下图所示:

t0128f824aa7ed65fdd.png

而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中,如下图所示:

t0128f824aa7ed65fdd.png

<?php
/**
 * 当有了IoC/DI的容器后,a类依赖c实例注入的示例
 */

/**
 * Class c
 */
class c
{
    public function say()
    {
        echo &#39;hello&#39;;
    }
}

/**
 * Class a
 */
class a
{
    private $c;
    public function setC(C $c)
    {
        $this->c = $c; // 实例化创建C类
    }

    public function sayC()
    {
        echo $this->c->say(); // 调用C类中的方法
    }
}

$c = new C();
$a = new a();
$a->setC($c);
$a->sayC();


声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn