国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Laravel Dependency Injection (依賴注入) 概念詳解

Fundebug / 2886人閱讀

摘要:依賴注入并不限于構造函數作為經驗,注入最適合必須的依賴關系,比如示例中的情況注入最適合可選依賴關系,比如緩存一個對象實例。

本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in PHP》 系列文章。

Part 1: What is Dependency Injection?

Part 2: Do you need a Dependency Injection Container?

Part 3: Introduction to the Symfony Service Container

Part 4: Symfony Service Container: Using a Builder to create Services

Part 5: Symfony Service Container: Using XML or YAML to describe Services

Part 6: The Need for Speed

依賴注入 設計模式非常簡單,但又很難解釋清楚。造成這個現象的主要原因是,別的介紹 依賴注入 的文章里太多廢話,讓人混淆。下面我將通過一些更適合 PHP 的例子來講解它。

HTTP 協議是無狀態的,我們的 Web 應用程序如果需要在請求之間存儲用戶信息,可以通過 COOKIESESSION

$_SESSION["language"] = "fr";

上述代碼中,我們將 language 存儲在全局變量 $_SESSION 中,因此可以這樣獲取它:

$user_language = $_SESSION["language"];

只有在 OOP 開發時中才會遇到 依賴注入 ,因此假設我們有一個封裝 SESSIONSessionStorage 類:

class SessionStorage
{
    function __construct($cookieName="PHPSESSID")
    {
        session_name($cookieName);
        session_start();
    }

    function set($key, $value)
    {
        $_SESSION[$key] = $value;
    }

    function get($key)
    {
        return $_SESSION[$key];
    }

    // ...
}

以及一個更高層的 User 類:

class User
{
    protected $storage;

    function __construct()
    {
        $this->storage = new SessionStorage();
    }

    function setLanguage($language)
    {
        $this->storage->set("language", $language);
    }

    function getLanguage()
    {
        return $this->storage->get("language");
    }

    // ...
}

這兩個類很簡單,并且用起來也很方便:

$user = new User();
$user->setLanguage("fr");
$user_language = $user->getLanguage();

這種方式看起來很完美,但是并不夠靈活。比如:現在想修改會話的 COOKIE 名稱(默認為 PHPSESSID) ,怎么辦?這時有一大堆辦法:

把會話的 COOKIE 名稱寫死在 User 類中 SessionStorage 的構造函數中 (Hardcode):

class User
{
    function __construct()
    {
        $this->storage = new SessionStorage("SESSION_ID");
    }

    // ...
}

或者在 User 類外面定義一個常量:

class User
{
    function __construct()
    {
        $this->storage = new SessionStorage(SESSION_COOKIE_NAME);
    }

    // ...
}

define("SESSION_COOKIE_NAME", "SESSION_ID");

或者把會話的 COOKIE 名稱作為 User 類構造函數的一個參數傳進去:

class User
{
    function __construct($cookieName)
    {
        $this->storage = new SessionStorage($cookieName);
    }

    // ...
}

$user = new User("SESSION_ID");

或者給 SessionStorage 類加個選項數組:

class User
{
    function __construct($storageOptions)
    {
        $this->storage = new SessionStorage($storageOptions["cookie_name"]);
    }

    // ...
}

$user = new User(["cookie_name" => "SESSION_ID"]);

上述方法都很糟糕:

把會話的 COOKIE 名稱寫死的話,每次想再改名,都要修改 User

使用常量的話,User 類的變化將取決于設置的常量

使用參數或者選項數組看起來很靈活,但它把與 User 本身無關的東西摻雜在了構造函數中

通過構造函數,把一個外部的 SessionStorage 實例"注入"進 User 實例內部,而不是在 User 實例內部創建 SessionStorage 實例,就是 依賴注入
class User
{
    function __construct($storage)
    {
        $this->storage = $storage;
    }

    // ...
}

很清爽吧!只需先創建 SessionStorage 實例,再創建 User 實例:

$storage = new SessionStorage("SESSION_ID");
$user = new User($storage);

用這個方法,配置 SessionStorage 很簡單,給 User 替換 $storage 類型也很簡單,都不需要去修改 User 類。這就實現了解耦。

依賴注入 并不限于構造函數:

Constructor Injection:

class User
{
    function __construct($storage)
    {
        $this->storage = $storage;
    }

    // ...
}

Setter Injection:

class User
{
    function setSessionStorage($storage)
    {
        $this->storage = $storage;
    }

    // ...
}

Property Injection:

class User
{
    public $sessionStorage;
}

$user->sessionStorage = $storage;

作為經驗, Constructor 注入 最適合必須的依賴關系,比如示例中的情況; Setter 注入 最適合可選依賴關系,比如緩存一個對象實例。

現在,大多數現代 PHP 框架都大量使用依賴注入來提供一組 去耦粘合 的組件:

// symfony: A constructor injection example
$dispatcher = new sfEventDispatcher();
$storage = new sfMySQLSessionStorage([
    "database" => "session",
    "db_table" => "session",
]);
$user = new sfUser($dispatcher, $storage, ["default_culture" => "en"]);

// Zend Framework: A setter injection example
$transport = new Zend_Mail_Transport_Smtp("smtp.gmail.com", [
  "auth"     => "login",
  "username" => "foo",
  "password" => "bar",
  "ssl"      => "ssl",
  "port"     => 465,
]);

$mailer = new Zend_Mail();
$mailer->setDefaultTransport($transport);

如果你有興趣了解更多有關 依賴注入 的信息,我強烈建議你閱讀 Martin Fowler 的介紹 或 Jeff Moore 的 PPT。你還可以看看我去年關于 依賴注入 的 PPT,其中我詳細了介紹本文中所討論的示例。

希望本文能讓你更好的理解 依賴注入,在本系列的下一部分中,我將討論 依賴注入容器 (Dependency Injection Containers)。

原創。 所有 Laravel 文章均已收錄至 laravel-tips 項目。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25954.html

相關文章

  • Laravel Container (容器) 概念詳解 (上)

    摘要:上文書,創建對象需要先創建對象。創建對象的雜活是嵌入在中的。對象使用來管理依賴關系非常好,但不是必須的。很容易實現,但手工維護各種亂七八糟的對象還是很麻煩。所有文章均已收錄至項目。 本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Depend...

    FullStackDeveloper 評論0 收藏0
  • Laravel Container (容器) 深入理解 (下)

    摘要:意味著依賴被注入進構造函數或者方法如果需要復用實例,可以定義為單例可以用接口或任何名稱來代替具體類。技能重寫構造函數參數方法允許將附加參數傳遞給構造函數。 本文大部分翻譯自 DAVE JAMES MILLER 的 《Laravel’s Dependency Injection Container in Depth》 。 上文介紹了 Dependency Injection Contai...

    eternalshallow 評論0 收藏0
  • 深入理解IoC(控制反轉)、DI(依賴注入

    摘要:引述最近看設計模式以及代碼,對于控制反轉以及依賴注入這些概念非常困惑,于是找了一些資料,以下是對于控制反轉的一下理解。其中最常見的方式叫做依賴注入,簡稱,還有一種方式叫依賴查找。在軟件工程中,依賴注入是種實現控制反轉用于解決依賴性設計模式。 引述 最近看設計模式以及laravel代碼,對于控制反轉以及依賴注入這些概念非常困惑,于是找了一些資料,以下是對于控制反轉的一下理解。 概念 Io...

    xcc3641 評論0 收藏0
  • 深入剖析 Laravel 服務容器

    摘要:劃下重點,服務容器是用于管理類的依賴和執行依賴注入的工具。類的實例化及其依賴的注入,完全由服務容器自動的去完成。 本文首發于 深入剖析 Laravel 服務容器,轉載請注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請求,又是如何生成響應并最終呈現給用戶的工作原理。 本章將帶領大...

    abson 評論0 收藏0
  • React 源碼深度解讀(六):依賴注入

    摘要:依賴注入和控制反轉,這兩個詞經常一起出現。一句話表述他們之間的關系依賴注入是控制反轉的一種實現方式。而兩者有大量的代碼都是可以共享的,這就是依賴注入的使用場景了。下一步就是創建具體的依賴內容,然后注入到需要的地方這里的等于這個對象。 前言 React 是一個十分龐大的庫,由于要同時考慮 ReactDom 和 ReactNative ,還有服務器渲染等,導致其代碼抽象化程度很高,嵌套層級...

    glumes 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<