<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 功能強大 支持多語言、二開方便! 廣告
                ## **依賴注入** 允許類的使用者為這個類注入依賴行為,通常情況下,這些依賴表現為對象、閉包或者回調方式;依賴注入的的思想就像它只給你家空調的遙控器提供電池,遙控器不會關心電池是哪個牌子、什么類型的牌子,你只需要滿足遙控器電池的尺寸和電壓 >[info]依賴注入關鍵:接口、多態、構造函數注入 將一個對象傳入另一個對象中(將對象以new時的構造函數或者方法傳入另一個類保存) **目的**:**為了提升組件重用的頻率** 希望日志類可以使用任意一個數據存儲引擎,即這個日志類依賴數據存儲引擎但不關心這些引擎怎么實現的 ``` <?php class Log{ protected $engine=false /** * 組裝日志信息并交給選定的日志引擎寫入日志 * @param [type] $message [description] */ public function add($message){ if(!$this->engine){ throw new Exception("引擎不存在無法寫入日志"); } $data['database']=time(); $data['message']=$message $session=Registry::get('session'); $data['user']=$message->getUSerID(); $this->engine->add($data); } /** * 設置日志引擎(文件、redis、數據庫等,本例以文件引擎為例) * @param Log_Engine_Interface $engine [description] */ public function setEngine(Log_Engine_Interface $engine){ $this->engine=$engine; } public function getEngine(){ return $this->engine; } } /** * 存儲引擎接口 */ interface Log_Engine_Interface{ /** * 添加日志事件 * @param array $data 事件內容 */ public function add(array $data); } /** * 文件存儲引擎 */ class Log_Engine_File implements Log_Engine_Interface{ /** * 日志寫入 * @param array $data [description] */ public function add(array $data){ $line='['.data('r',$data['datetime']).']'.$data['message'].'User:'.$data['user'].PHP_EOL $config=Registry::get('site-config'); if(!file_put_contents($config['location'],$line,$flags=FILE_APPEND)){ throw new Exception("寫入出錯"); } } } $engine=new Log_Engine_File(); $Log=new Log(); $log->setEngine($engine); $Registry::add($log); ``` 常規的想在注冊完成后發送一個郵件的寫法 ``` //1 Email.class.php發送郵件的類 class Mail{ public function send(){ //發送郵件的具體代碼 } } //2底層代碼: 由注冊的類'Register.clas10s.php' 里調用send()發送 class Register{ private $_emailObject; public function doRegister(){ //這里是如何注冊 $this->$_emailObject = new Mail();//對象 $this->$_emailObject->send();//發送郵件(連續調用) } } //3上層代碼: 某個注冊頁面: include 'Mail.class.php'; include 'Register.class.php'; $reg = new Register(); $reg->doRegister(); ``` xxx天過后,產品人員說發送郵件的不好,要使用發送短信的,然后你說這簡單我把'Mail'類改下 然后你必須將底層代碼Register類的doRegister()里的內容`new Mail()`修改為`new Message()` 怎么解決了'Register'對信息發送類的依賴呢? 利用接口的多態性 使用構造函數注入的方法,使得它只依賴于發送短信的接口,只要實現其接口中的'send'方法,不管你怎么發送都可以(除了構造函數注入,還有方法注入及屬性注入 ) ``` //修改后 //1 Mail.class.php各種方式發送消息的類 interface Mail{ public function send();//接口類的方法全是公共public 的抽象方法 子類必須全部繼承接口的父類 } class Email implements Mail{ public function send(){ //發送email } } class SmsMail implements Mail{ public function send(){ //發送短信 } } //2然后又注冊后又要發送消息的類'Register.class.php' class Register{ private $_mailObj; public function __construct(Mail $mailObj){ $this->_mailObj=$mailObj;//初始化發送方式 } public function doRegister(){ $this->_mailObj->send();//發送消息 } } //3 注冊頁面 function run(){ $reg = new Register();//實例化注冊類 $emailObj = new Email(); $smsMail = new SmsMail(); $reg->doRegister($emailObj);//用email發送 $res->doRegister($smsMail);//用短信發送 } run(); //較好的封裝 class Client{ public static function main(){ $mother = new Register(); $emailObj = new Email(); $smsMail = new SmsMail(); $mother->narrate(emailObj); $mother->narrate(smsMail); } } $client = new Client(); $client->main(); ``` 上面的代碼解決了'Register'對信息發送類的依賴,使用構造函數注入的方法,使得它只依賴于發送短信的接口,只要實現其接口中的'send'方法, 注意在這里上面的必須先引入信息發送類在引入注冊類 怎么解決引入加載順序呢,這就需要用到依賴倒置啦,上面例子很好的實現了該思想,實例化注冊類Register的時候加上了類型限制,如果傳入的是信息發送類則實例化成功否則會報錯 **依賴倒置原則**(`Dependence Inversion Principle` `DIP`)思想的定義是“**高層模塊不應該依賴低層模塊,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象** 傳統軟件設計中,上層代碼依賴于下層代碼,當下層出現變動時, 上層代碼也要相應變化,維護成本較高。而DIP的核心思想是上層定義接口,下層實現這個接口, 從而使得下層依賴于上層,降低耦合度,提高整個系統的彈性。這是一種經實踐證明的有效策略。 ***** ***** 依賴注入(DI)和控制反轉(IOC)基本是一個意思,因為說起來誰都離不開誰。 **依賴注入(DI):** 簡單來說,a依賴b,但a不控制b的創建和銷毀,僅使用b,那么b的控制權交給a之外處理,這叫控制反轉(IOC),而a要依賴b,必然要使用b的instance,那么 >[info] 通過a的接口,把b傳入; >通過a的構造,把b傳入; > 通過設置a的屬性,把b傳入; 這個過程叫依賴注入(DI)。 **IOC Container:** 隨著依賴注入(DI)的頻繁使用,要實現控制反轉(IOC),會有很多重復代碼,甚至隨著技術的發展,有更多新的實現方法和方案,那么有人就把這些實現控制反轉(IOC)的代碼打包成組件或框架,來避免人們重復造輪子。 所以實現控制反轉(IOC)的組件或者框架,我們可以叫它IOC Container。 大多數面向對象編程語言,在調用一個類的時候,先要實例化這個類,生成一個對象。 如果你在寫一個類,過程中要調用到很多其它類,甚至這里的其它類,也要“依賴”于更多其它的類,那么可以想象,你要進行多少次實例化。這就是“依賴”的意思。 依賴注入,全稱是“依賴注入到容器”, 容器(IOC容器)是一個設計模式,它也是個對象,你把某個類(不管有多少依賴關系)放入這個容器中,可以“解析”出這個類的實例。 所以依賴注入就是把有依賴關系的類放入容器(IOC容器)中,然后解析出這個類的實例。僅此而已 推薦一篇博文:[依賴注入和控制反轉的理解,寫的太好了](https://blog.csdn.net/liunianqingshi/article/details/78144489)
                  <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>

                              哎呀哎呀视频在线观看