聽 Fabien Potencier 談Symfony2 之 《What is Dependency Injection ?》

來源:互聯網
上載者:User

標籤:blog   http   使用   os   io   資料   art   ar   

什麼是依賴注入?
從PHP實現角度來分析依賴注入,因為PHP主要用於web開發,所以我們就看Web應用例子。
為了克服HTTP協議的無狀態性,web應用程式需要有一個途徑來在web請求之間儲存使用者資訊。最簡單的方式是使用cookie或者採用更好一點的PHP內建的Session機制。

$_SESSION[‘language‘]=‘en‘;

上面這句代碼就實現了把語言儲存到Session變數language裡。從此之後,同一使用者一些後續的請求都可以使用這個值了。因為$_SESSION 數組是個全域的變數。調用方式如下:

$user_language = $_SESSION[‘language‘];

因為依賴注入是物件導向世界裡的概念,現在我們需要把PHP Session機制封裝到一個類裡面,然後應用到web應用程式中。

class SessionStorage{   function __construct($cookieName = ‘PHP_SESS_ID‘)   {    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(‘en‘);$user_language = $user->getLanguage();

如果做得更加靈活一點呢?你想改變會話cookie的名字怎麼辦?有幾個方式:可以在User類中在SessionStorage的建構函式中指定,即一種寫入程式碼方式。

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

      或者在User類外面定義一個常量:STORAGE_SESSION_NAME 這種全域式的常量定義,不推薦。

class User{  function __construct()  {    $this->storage = new SessionStorage(STORAGE_SESSION_NAME);  }   // ...}define(‘STORAGE_SESSION_NAME‘,‘SESSION_ID‘);

一種方式是把Session名作為User 類建構函式的參數:

class User{  function __construct($sessionName)  {    $this->storage = new SessionStorage($sessionName);  }   // ...} $user = new User(‘SESSION_ID‘);

    還有一種方式是PHP代碼中常見的為Session儲存類添加一個可選設定項數組options 

class User{  function __construct($storageOptions)  {    $this->storage = new SessionStorage($storageOptions[‘session_name‘]);  }   // ...} $user = new User(array(‘session_name‘ => ‘SESSION_ID‘));

實現的方法有很多啊,無論是寫入程式碼,設定為常量,作為建構函式的參數還是可選項數組都不是最佳選擇。雖然後兩者看起來好那麼一點點,但它讓User類的構造器堆積了一些跟自己沒關係的參數。

繼續,另外一個問題又來了,如果我想改變SessionStorage類怎麼辦?比如在測試時,製造個假資料。或者你想把Session儲存到資料庫或者記憶體中時,就需要改變SessionStorage類了。就目前情況來看,如果不修改User類是不可能實現改變SessionStorage類的。

現在我們考慮依賴注入,我們不在User類中建立SessionStorage對象,而是在外部建立後作為User類的構造方法參數傳遞給User對象。

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

OK,這就是依賴注入,沒別的了!現在再使用User類時可能需要比上次麻煩一點:

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

現在在不改變User類的前提下,改變Session名字,改變SessionStorage類,你想幹啥都行了!

總結一下:依賴注入是組件們通過他們的構造器,方法,或者屬性欄位來擷取他們依賴的對象。

構造器注入:

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

設定器注入(方法注入):

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

屬性欄位注入:

class User{  public $sessionStorage;} $user->sessionStorage = $storage;

這些在Symfony 中你都會看到他們的身影:

構造注入:

$dispatcher = new sfEventDispatcher();$storage = new sfMySQLSessionStorage(array(‘database‘ => ‘session‘, ‘db_table‘ => ‘session‘));$user = new sfUser($dispatcher, $storage, array(‘default_culture‘ => ‘en‘));

將$dispatcher對象和$storage對象注入到$user對象中。

方法注入:

$transport = new Zend_Mail_Transport_Smtp(‘smtp.gmail.com‘, array(  ‘auth‘     => ‘login‘,  ‘username‘ => ‘foo‘,  ‘password‘ => ‘bar‘,  ‘ssl‘      => ‘ssl‘,  ‘port‘     => 465,)); $mailer = new Zend_Mail();$mailer->setDefaultTransport($transport);

該注入俗稱為setter注入。

Ok,這就是依賴注入了,它會在Symfony2中發展到服務容器注入。 以提供更加方便靈活鬆散耦合的多級依賴管理。它就是Service Container,它為Symfony2的執行效率和可擴充性提供了最強大的支援。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.