zoukankan      html  css  js  c++  java
  • 关于依赖注入的思考

    最近几日接触了一个PHP API框架,其中里面用到了依赖注入的思想。于是自己写下了一个小例子来加深印象:

      1 <?php
      2 //https://docs.phalconphp.com/zh/latest/reference/di.html
      3 /**
      4  * Log接口
      5  * Interface ILog
      6  */
      7 interface ILog {
      8     public function info($str);
      9 
     10     public function error($str);
     11 }
     12 
     13 /**
     14  * 数据库log,实现log接口
     15  * Class DBLog
     16  */
     17 class DBLog implements ILog {
     18     private $_name;
     19 
     20     public function __construct($name) {
     21         $this->_name = $name;
     22     }
     23 
     24     public function info($str) {
     25         echo '<br>[DBLog][' . $this->_name . '][info]call log info function: ' . $str . '<br>';
     26     }
     27 
     28     public function error($str) {
     29         echo '<br>[DBLog][' . $this->_name . '][error]call log info function: ' . $str . '<br>';
     30     }
     31 }
     32 
     33 /**
     34  * 文件log,实现log接口
     35  * Class FileLog
     36  */
     37 class FileLog implements ILog {
     38     private $_name;
     39 
     40     public function __construct($name) {
     41         $this->_name = $name;
     42     }
     43 
     44     public function info($str) {
     45         echo '<br>[FileLog][' . $this->_name . '][info]call log info function: ' . $str . '<br>';
     46     }
     47 
     48     public function error($str) {
     49         echo '<br>[FileLog][' . $this->_name . '][error]call log info function: ' . $str . '<br>';
     50     }
     51 }
     52 
     53 /**
     54  * 依赖注入类
     55  * 用于存放需要依赖的类的容器
     56  * Class DI
     57  */
     58 class DI {
     59     public $arr = array();
     60     protected static $instance = NULL;
     61 
     62     public static function getInstance() {//单例加载
     63         if (self::$instance == NULL) {
     64             self::$instance = new DI();
     65         }
     66         return self::$instance;
     67     }
     68 
     69     public function __set($name, $value) {//魔法方法 设置私有属性值
     70         $this->set($name, $value);
     71     }
     72 
     73     public function __get($name) {
     74         $this->get($name);
     75     }
     76 
     77     public function set($key, $value) {
     78         $this->arr[$key] = $value;
     79     }
     80 
     81     public function get($key, $default = NULL) {
     82         return $this->arr[$key];
     83     }
     84 }
     85 
     86 /**
     87  * 主类
     88  * Class User
     89  */
     90 class User {
     91 
     92     private $_di;
     93 
     94     public function __construct($di) {
     95         //使用依赖注入容器,目的是防止出现多个setter方法分别设置不同依赖项
     96         $this->_di = $di;
     97     }
     98 
     99     public function writeLog($str) {
    100         //从DI容器中获取要操作的类/对象
    101         $obj = $this->_di->get('logger');
    102         $obj->info($str);
    103         $obj->error($str);
    104     }
    105 
    106     public function run() {
    107         $obj = $this->_di->get('fun');
    108         $obj()->callRuntime();
    109     }
    110 }
    111 
    112 class Runtime {
    113     public function __construct() {
    114         var_dump('call Runtime construct');
    115     }
    116 
    117     public function callRuntime() {
    118         var_dump('call Runtime');
    119     }
    120 }
    121 
    122 //客户端调用
    123 echo '<br>=======begin========<br>';
    124 $di = DI::getInstance();
    125 $di->logger = new DBLog('mydb');//魔法方法 设置私有属性值
    126 $user = new User($di);
    127 $user->writeLog('lalala');
    128 
    129 echo '<br>===============<br>';
    130 $di2 = DI::getInstance();
    131 $di2->logger = new FileLog('myfile');
    132 
    133 $di2->fun = function () {//延迟加载
    134     return new Runtime();
    135 };
    136 
    137 
    138 //$di2->set('logger',new FileLog('myfile')); 与上面的方式等效
    139 $user2 = new User($di2);//切换依赖项,主类(User类)不需要改一行代码(前提是不同依赖项实现相同的接口)
    140 $user2->writeLog('bababa');
    141 $user2->run();
    142 echo '<br>=======end========<br>';
    143 
    144 //返回结果:
    145 /*
    146 
    147 =======begin========
    148 
    149 [DBLog][mydb][info]call log info function: lalala
    150 
    151 [DBLog][mydb][error]call log info function: lalala
    152 
    153 ===============
    154 
    155 [FileLog][myfile][info]call log info function: bababa
    156 
    157 [FileLog][myfile][error]call log info function: bababa
    158 
    159 string 'call Runtime construct' (length=22)
    160 
    161 string 'call Runtime' (length=12)
    162 
    163 
    164 =======end========
    165 */
  • 相关阅读:
    LeetCode 152. 乘积最大子数组
    LeetCode 148. 排序链表
    LeetCode 143. 重排链表
    LeetCode 142. 环形链表 II
    LeetCode 137. 只出现一次的数字 II
    LeetCode 127. 单词接龙
    LeetCode 120. 三角形最小路径和
    spring boot redis 数据库缓存用法
    堪称神器的Chrome插件
    rocketMQ安装中遇到的坑
  • 原文地址:https://www.cnblogs.com/dannywang/p/4740386.html
Copyright © 2011-2022 走看看