Laravel 依賴注入思想

依賴注入

依賴注入是個花俏的名詞,事實上是指:類的依賴經過構造器或在某些狀況下經過「setter」方法「注入」。先看一段 Laravel 控制器裏的代碼實例:php

<?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('user', ['user_info' => $user_info]);
    }
}

Laravel 經過服務容器來管理類依賴並進行依賴注入。若是使用一個接口做爲函數參數的類型提示,這個時候就須要將指定的實現綁定到接口上面:html

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

/**
 * 建立一個新的類實例。
 *
 * @param  EventPusher  $pusher
 * @return void
 */
public function __construct(EventPusher $pusher)
{
    $this->pusher = $pusher;
}

這個就是所謂的面向接口編程,接口能夠理解爲一個規範、一個約束。高層模塊不直接依賴於低層模塊,它們都應該依賴於抽象(指接口)。java

使用依賴注入,最重要的一點好處就是有效的分離了對象和它所須要的外部資源,使得它們鬆散耦合,有利於功能複用,更重要的是使得程序的整個體系結構變得很是靈活。laravel

控制反轉

控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則。其中**最多見的方式叫作依賴注入(Dependency Injection,簡稱DI),還有一種方式叫「依賴查找」(Dependency Lookup)。經過控制反轉,對象在被建立的時候,由一個調控系統內全部對象的外界實體,將其所依賴的對象的引用傳遞給它。也能夠說,依賴被注入到對象中。程序員

clipboard.png

<?php
/**
 * 沒有IoC/DI的時候,常規的A類使用C類的示例
 */

/**
 * Class c
 */
class c
{
    public function say()
    {
        echo 'hello';
    }
}

/**
 * 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了,以下圖所示:編程

而是被動等待,等待IoC/DI的容器獲取一個C的實例,而後反向的注入到A類中,以下圖所示:segmentfault

<?php
/**
 * 當有了IoC/DI的容器後,a類依賴c實例注入的示例
 */

/**
 * Class c
 */
class c
{
    public function say()
    {
        echo 'hello';
    }
}

/**
 * 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();

參考連接

  1. 類型約束app

  2. PHP 依賴注入,今後再也不考慮加載順序函數

  3. Java基礎:面向對象三大特徵、五大原則oop

  4. 依賴倒置原則

  5. PHP程序員如何理解依賴注入容器(dependency injection container)

  6. 聊一聊PHP的依賴注入(DI) 和 控制反轉(IoC)

  7. 深刻探討依賴注入

  8. 服務容器

相關文章
相關標籤/搜索