首頁  >  文章  >  後端開發  >  phalapi之DI依賴注入與單例實現

phalapi之DI依賴注入與單例實現

*文
*文原創
2017-12-23 16:48:331870瀏覽

單利模式和依賴注入,相信很多人都不陌生。本文主要講解了phalapi的DI依賴注入和單例模式,對依賴注入和單例模式有興趣的同學可以看一下。

1. 單例模式

單例模式對於長期進行過物件導向程式設計的童鞋應該不算陌生,在學習php的童鞋也應該有聽過,這裡簡單的聊一聊單例模式到底是一個怎麼樣東西,解決了什麼問題,並且在PhalApi中是如何實現的.

單例單例,所謂單例也就是有且只有一個存在,這就是單例,不難看出他的好處資源利用少因為只有一個,大家都是知道要使用一個類別必須要實例他也就是new在每次new一個物件的時候都會在記憶體中產生一塊區域來存放這個實例,如果在程式一次運行中使用了很多的new實例化了同一個物件,那就比較消耗資源了,但是如果是通用一個使用全域變數global程式又會顯得不優雅而且會很亂,在這種​​情況下單例模式就產生了.


單例模式就是一個兩全其美的一個方法既可以全局通用,二不用擔心佔用過多的資源,三又非常優雅,讓我們來一起看看在PhalApi中是如何實作單例模式的:

//大家看到我们常用的DI方法内部实现的是PhalApi_DI中的静态方法one方法
function DI() {
    return PhalApi_DI::one();
}

然後我們看向one方法內部


每當我們要求過來的時候先驗證靜態變數instance是不是沒有被初始化,如果是第一次呼叫他會在內部去實例化PhalApi_DI類​​別然後負值給$instance然後返回實例好的這個靜態變數,當我們下次在請求過來的時候這個靜態變數已經被實例化好了就會直接跳過實例的過程直接返回這個物件,也就是我們在PhalApi框架所有的地方使用的DI方法其實都是一個物件,在記憶體中只存在一塊區域,程式碼如下:

public static function one(){
    if(self::$instance == NULL){
        self::$instance = new PhalApi_DI();
        self::$instance->onConstruct();
    }
    return self::$instance;
}

其實不難我們只用吧new一個類別的操作封裝到我們需要new的類別的靜態方法在向上面一樣的去判斷,就可以很簡單的去實作單例模式.


2. 依賴注入

依賴注入又稱之為"控制反轉",如果是熟悉javaweb開發的spring框架應該有比較深的感觸,在這裡也不往深的講,就簡單講解一下PhalApi中DI依賴注入的實現讓大家了解這種設計模式如何實現以及自此基礎上實現的惰性加載機制.


2.1 DI依賴注入實作

大家在PhalApi中常用的DI()方法,也就是採用我們上面所謂的單例模式不用多說了,也就是我們每次使用DI()其實就是在使用PhalApi_DI類​​別,那麼我們依賴注入的關鍵也就是在PhalApi_DI之中


先來講一下他的一個實作方式在來講具體實作,這裡舉個例子:

//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');

其實在內部有一個陣列,它吧config作為了key,吧new PhalApi_Config_File(API_ROOT . '/Config')作為了value然後保存了起來當我們下次使用DI->config->get();的時候它就會根據key值config拿出開始new好的類別,所以可以說config操作是依賴DI(),而且在使用DI() ->config的時候永遠都是在使用的一個實例,也能減少資源的消耗.

有的童鞋就好奇了為什麼DI()->config會存到數組需要的時候會拿出來呢,有興趣的童鞋可以百度一下魔法方法ser和get

/**大家可以看到这是PhalApi_DI中的魔法方法__set
 * 也就是当使用DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');的时候
 * 获得的name值就是config,获得的value也就是new PhalApi_Config_File(API_ROOT . '/Config');
 */get同理,在内部实现都是调用了内部get和set方法
public function __set($name, $value){
    $this->set($name, $value);
}
public function __get($name){
    return $this->get($name, NULL);
}

看完之後大家是不是覺得很簡單啊,大家以後也可以在自己設計類的時候採用這種靈活的魔法方法實作.


2.2 惰性載入

在PhalApi中的DI()方法也提供惰性載入,惰性載入如字意也就是當類別沒有被使用到的時候不會載入,這樣的操作也是為了避免浪費不必要的資源,當我們不是用的時候永遠不會去實例化只有當你使用到的時候才會去new這個類別然後實例化之後使用,我們來看看是如何實現的.

//当我们执行以下语句的时候,在依赖注入的时候存的是value值是字符串的test
DI()->test = 'test';
//使用DI()->test->test();的时候会使用到PhalApi中的get方法,在get方法中有一段代码
$this->data[$key] = $this->initService($this->data[$key]);
//在initService方法内部验证了value是字符串就实例化了再返回
if($config instanceOf Closure){
    $rs = $config();
}elseif(is_string($config) && class_exists($config)){
    $rs = new $config();
    if(is_callable(array($rs, 'onInitialize'))){
        call_user_func(array($rs, 'onInitialize'));
    }
}else{
    $rs = $config;
}

相關推薦:

phalapi之如何實現資料庫讀寫分離

phalapi-快取的使用以及redis拓展

PhalApi(π框架)

以上是phalapi之DI依賴注入與單例實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn