<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                _一個沒有絕對答案的世界,卻擁有絕對的豐富。 --《沈奇嵐:我愿生命從容》_ ##2.11.1 定義 ###(1) 關于依賴注入 即控制反轉,目的是了減少耦合性,簡單來說就是使用開放式來獲取需要的資源。 ###(2) 關于資源 這里說的資源主要是在開發過程中使用到的資源,包括配置項;數據庫連接、Memcache、接口請求等系統級的服務;以及業務級使用到的實例等。 引入依賴注入的目的不僅是為了增加一個類,而是為了更好的對資源進行初始化、管理和維護。下面將進行詳細的說明。 ##2.11.2 一個簡單的例子 很多時候,類之間會存在依賴、引用、委托的關系,如A依賴B時,可以這樣使用: ```javascript class A { protected $_b; public function __construct() { $this->b = new B(); } } ``` 這種方式在A內限制約束了B的實例對象,當改用B的子類或者改變B的構建方式時,A需要作出調整。這時可以通過依賴來改善這種關系: ```javascript class A { protected $_b; public function __construct($b) { $this->b = $b; } } ``` 再進一步,可以使用DI對B的對象進行管理: ```javascript class A { public function __construct() { } public function doSth() { //當你需要使用B時 $b = $di->get('B'); } } ``` 這樣的好處? 一方面,對于使用A的客戶(指開發人員),不需要再添加一個B的成員變量,特別不是全部類的成員函數都需要使用B類服務時。另一方面在外部多次初始化A實例時,可以統一對B的構建。 ##2.11.3 依賴注入的使用示例 為方便使用,調用的方式有:set/get函數、魔法方法setX/getX、類變量$fdi->X、數組$fdi['X'],初始化的途徑有:直接賦值、類名、匿名函數。 ```javascript /** ------------------ 創建與設置 ------------------ **/ //獲取DI $di = DI(); //演示的key $key = 'demoKey'; /** ------------------ 設置 ------------------ **/ //可賦值的類型:直接賦值、類名賦值、匿名函數 $di->set($key, 'Hello DI!'); $di->set($key, 'Simple'); $di->set($key, function(){ return new Simple(); }); //設置途徑:除了上面的set(),你還可以這樣賦值 $di->setDemoKey('Hello DI!'); $di->demoKey = 'Hello DI!'; $di['demoKey'] = 'Hello DI!'; /** ------------------ 獲取 ------------------ **/ //你可以這樣取值 echo $di->get('demoKey'), "\n"; echo $di->getDemoKey(), "\n"; echo $di->demoKey, "\n"; echo $di['demoKey']. "\n"; /** * 演示類 */ class Simple { public function __construct() { } } ``` ##2.11.4 依賴注入的好處 ###(1)減少對各個類編寫工廠方法以單例獲取的開發量 DI相當于一個容器,里面可以放置基本的變量,也可以放置某類服務,甚至是像文件句柄這些的資源。在這容器里面,各個被注冊的資源只會存在一份,也就是當被注冊的資源為一個實例對象時,其效果就等于單例模式。 因此,保存在DI里面的類,不需要再編寫獲取單例的代碼,直接通過DI獲取即可。 例如很多API的服務組件以及其他的一些類,都實現了單例獲取的方式。分別如: 微博接口調用: ```javascript <?php class Weibo_Api { protected static $_instance = null; public static function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new Weibo_Api(); } return self::$_instance; } //.... } ``` 七牛云存儲接口調用: ```javascript class Qiniu_Api { private static $_instance = null; //實例對象 public static function getInstance() { if (self::$_instance ===null) { self::$_instance = new Qiniu_Api(); } return self::$_instance; } } ``` QQ開放平臺接口調用: ```javascript class QQ_Api { private static $_instance = null; //實例對象 public static function getInstance() { if (self::$_instance ===null) { self::$_instance = new QQ_Api(); } return self::$_instance; } } ``` 如果使用DI對上面這些服務進行管理,則上面三個類乃至其他的類對于單例這塊的代碼都可以忽略不寫。注冊代碼如下: ```javascript $di->sStockApi = 'Weibo_Api'; $di->sDioAopi = 'Qiniu_Api'; $di->sShopApi = 'QQ_Api'; ``` 上面是通過類名來進行延遲加載,但需要各個類提供public的無參數的構造函數。如果各個服務需要進行初始化,可以將初始化的工作放置在onInitialize()函數內,DI在對類實例化時會回調此函數進行初始化。 ###(2)統一資源注冊,便于后期維護管理 這里引入DI,更多是為了“一處創建,多處使用”, 而不是各自創建,各自使用。 ####創建和使用分離 考慮以下場景:假設有這樣的業務數據需要緩存機制,所以可注冊一個實現緩存機制的實例: ```javascript $di->set('cache', new FileCache()); ``` 然后提供給多個客戶端使用: ```javascript $di['cache']->set('indexHtml', $indexContent); //緩存頁面 $di['cache']->set('config', $config); //緩存公共配置 $di['cache']->set('artistList', $artistList); //緩存數據 ``` 當需要切換到MC或者Redis緩存或者多層緩存時,只需要修改對緩存機制的注入即可,如: ```javascript $di->set('cache', new RedisCache()); ``` 依賴注入的一個很大的優勢就在于可以推遲決策,當需要用到某個對象時,才對其實例化。可以讓開發人員在一開始時不必要關注過多的細節實現,同時也給后期的擴展和維護帶來極大的方便。 再上一層,假設未來我們需要更高級的緩存服務,那么我們可以在不影響客戶端使用的情況下,輕松升級。 未來的可配置化的多級緩存策略 以下是一個模擬的使用場景,但依然對現在的項目有一定的幫助。假設我們現在有一個MC集群的緩存且引入了DI,使用如下: ```javascript <?php //初始化 $di = Core_DI::one(); $di->cache = new Memcache(); $di->cache->connect('localhost', 11211); //不同文件的多處使用 ... echo $di->cache->get('key'); echo $di->cache->get('key2'); echo $di->cache->get('key3'); ... ``` 假設現在發現一層緩存存在穿透情況,為保證服務器的穩定性,我們已開發實現了多層緩存策略,并且可以通過簡單配置即可實現,只需要對DI容器里面的cache實例進行升級,其他客戶端的調用即可馬上享受到緩存升級的優質服務。升級涉及改動的代碼如下: ```javascript <?php //初始化 $di = new Core_DI(); $di->cache = function () { $ultraFastFrontend = new DataFrontend(array( "lifetime" => 3600 )); $fastFrontend = new DataFrontend(array( "lifetime" => 86400 )); $slowFrontend = new DataFrontend(array( "lifetime" => 604800 )); return new Multiple(array( new ApcCache($ultraFastFrontend, array( "prefix" => 'cache', )), new MemcacheCache($fastFrontend, array( "prefix" => 'cache', "host" => "localhost", "port" => "11211" )), new FileCache($slowFrontend, array( "prefix" => 'cache', "cacheDir" => "../app/cache/" )) )); }; ``` 備注:關于多級緩存策略,后續會提供源代碼和重用庫,或者期待讀者的分享。 ###(3)延遲式加載,提高性能 延遲加載可以通過DI中的類名初始化、匿名函數和參數配置(未實現)三種方式來實現。 延遲加載有時候是非常有必要的,如在初始化項目的配置時,隨著配置項的數據增加,服務器的性能也將逐漸受到影響,因為配置的內容可能是硬編碼,可能來自于數據庫,甚至需要通過接口從后臺調用獲取, 特別當很多配置項不需要使用時。而此時,支持延時加載將可以達到很好的優化,而不用擔心在需要使用的時候忘記了初始化。從而很好的提高服務器性能,提高響應速度。 如對一些耗時的資源先進行匿名函數的初始化: ``` $di['hightResource'] = function() { //獲取返回耗性能的資源 //return $resource; } ``` ###(4)以優雅的方式取代濫用的全局變量 在我看來,PHP里面是不應該使用全局變量(global和$_GLOBALS),更不應該到處使用。 用了DI來管理,即可這樣注冊: ```javascript $di->set('debug', true); ``` 然后這樣使用: ```javascript $debug = $di->get('debug'); ``` 也許有人會想:僅僅是換個地方存放變量而已嗎?其實是換一種思想使用資源。 以此延伸,DI還可用于改善優化另外兩個地方:通過include文件途徑對變量的使用和變量的多層傳遞。 變量的多層傳遞,通俗來說就是漂洋過海的變量。 ##2.11.5 DI思想的來源與推薦參考 [Dependency Injection/Service Location](http://docs.phalconphp.com/en/latest/reference/di.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看