PHP中的服務容器與依賴注入的解析

來源:互聯網
上載者:User
這篇文章主要介紹了關於PHP中的服務容器與依賴注入,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

依賴注入

當A類需要依賴於B類,也就是說需要在A類中執行個體化B類的對象來使用時候,如果B類中的功能發生改變,也會導致A類中使用B類的地方也要跟著修改,導致A類與B類高耦合。這個時候解決方式是,A類應該去依賴B類的介面,把具體的類的執行個體化交給外部。

就拿我們業務中常用的通知模組來說。

<?php/** * 定義了一個訊息類 * Class Message  */class  Message{  public function seed()  {      return 'seed email';  }}/* * 訂單產生的時候 需要發送訊息 */class Order{    protected $messager = '';    function __construct()    {        $this->messager = new Message();    }    public function seed_msg()    {        return $this->messager->seed();    }}$Order = new Order();$Order->seed_msg();

上面的代碼是我們傳統的寫法。首先由個訊息發送的類。然後在我們需要發送訊息的地方,調用發送訊息的介面。有一天你需要添加一個傳送簡訊的介面以滿足不同的需求。那麼你會發現你要再Message類裡面做修改。同樣也要再Order類裡面做修改。這樣就顯得很麻煩。這個時候就有了依賴注入的思路。下面把代碼做一個調整

<?php/** * 為了約束我們先定義一個訊息介面 * Interface Message */interface  Message{  public function seed();}/** * 有一個發送郵件的類 * Class SeedEmail */class SeedEmail implements Message{    public function seed()    {        return  'seed email';        // TODO: Implement seed() method.    }}/**  *新增一個傳送簡訊的類 * Class SeedSMS */class SeedSMS implements Message{    public function seed()    {        return 'seed sms';        // TODO: Implement seed() method.    }}/* * 訂單產生的時候 需要發送訊息 */class Order{    protected $messager = '';    function __construct(Message $message)    {        $this->messager = $message;    }    public function seed_msg()    {        return $this->messager->seed();    }}//我們需要發送郵件的時候$message = new SeedEmail();//將郵件發送對象作為參數傳遞給Order$Order = new Order($message);$Order->seed_msg();//我們需要傳送簡訊的時候$message = new SeedSMS();$Order = new Order($message);$Order->seed_msg();

這樣我們就實現了依賴注入的思路,是不是很方便擴充了。

服務容器

我理解的服務容器就是一個自動產生類的工廠。
<?php/** * 為了約束我們先定義一個訊息介面 * Interface Message */interface  Message{    public function seed();}/** * 有一個發送郵件的類 * Class SeedEmail */class SeedEmail implements Message{    public function seed()    {        return  'seed email';        // TODO: Implement seed() method.    }}/** *新增一個傳送簡訊的類 * Class SeedSMS */class SeedSMS implements Message{    public function seed()    {        return 'seed sms';        // TODO: Implement seed() method.    }}/** * 這是一個簡單的服務容器 * Class Container */class Container{    protected $binds;    protected $instances;    public function bind($abstract, $concrete)    {        if ($concrete instanceof Closure) {            $this->binds[$abstract] = $concrete;        } else {            $this->instances[$abstract] = $concrete;        }    }    public function make($abstract, $parameters = [])    {        if (isset($this->instances[$abstract])) {            return $this->instances[$abstract];        }        array_unshift($parameters, $this);        return call_user_func_array($this->binds[$abstract], $parameters);    }}//建立一個訊息工廠$message = new  Container();//將傳送簡訊註冊綁定到工廠裡面$message->bind('SMS',function (){     return   new  SeedSMS();});//將發送郵件註冊綁定到工廠$message->bind('EMAIL',function (){   return new  SeedEmail();});//需要傳送簡訊的時候$SMS  = $message->make('SMS');$SMS->seed();

container是一個簡單的服務容器裡面有bind,make兩個方法
bind是向容器中綁定服務物件。make則是從容器中取出對象。

bind

bind方法中需要傳入一個 concrete 我們可以傳入一個執行個體對象或者是一個閉包函數。
可以看到我這全使用的是閉包函數,其實也可以這樣寫

$sms = new  SeedSMS();$message->bind('SMS',$sms);

後面這種寫法與閉包相比的區別就是我們需要先執行個體化對象才能往容易中綁定服務。而閉包則是我們使用這個服務的時候才去執行個體化對象。可以看出閉包是有很多的優勢的。

make

make方法就從容器中出去方法。裡面首先判斷了instances變數中是否有當前以及存在的服務物件,如果有直接返回。如果沒有那麼會通過 call_user_func_array返回一個對象。call_user_func_array的使用可以查看
PHP 中 call_user_func 的使用

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.