• Swoole实战之手撸HttpServer框架 3 依赖注入反转控制 、Ioc容器、第三方DI库


    0 传统方法,正向控制

    <?php
    class MyDB
    {
       private $db;
       public function __construct($connInfo)
       {
       }
       
       public function gueryForRows($sql)
       {
           return ['uid'=>111];
       }
    }
    
    class MyUser
    {
        public $mydb;
        public function __construct($dsn)
        {
            //正向实例化 以myUser控制MyDB
            $this->mydb = new MyDB($dsn);
        }
        
        public function getAllUsers():array {
            return $this->mydb->gueryForRows('select * from users');
        }
    }
    
    $user = new MyUser('mysql:host=localhost');
    $list = $user->getAllUsers();
    var_dump($list);
    View Code

    缺点:过度耦合。

    1 改进版本1.0 依赖注入、控制反转

    <?php
    class MyDB
    {
       private $db;
       public function __construct($connInfo)
       {
       }
       
       public function gueryForRows($sql)
       {
           return ['uid'=>222];
       }
    }
    
    class MyUser
    {
        public $mydb;
        //$dsn配置
        // 1 正向控制 public function __construct($dsn)
        public function __construct(MyDB $DB)
        {
            //1 正向实例化 以myUser控制MyDB
            //$this->mydb = new MyDB($dsn);
            //MyUser不会主动去实例化DB 控制顺序发生了反转 起到了解耦的目的
            $this->mydb = $DB;
        }
        
        public function getAllUsers():array {
            return $this->mydb->gueryForRows('select * from users');
        }
    }
    
    // $user = new MyUser('mysql:host=localhost');
    $db = new MyDB('mysql:host=localhost');
    //依赖注入 控制反转    向MyUser注入MyDB的实例
    $user = new MyUser($db);
    
    
    $list = $user->getAllUsers();
    var_dump($list);

    优点:MyUser不再主动创建MyDB实例,变成被动等待依赖注入。起到了解耦的目的

    2 IoC容器2.0

    <?php
    class MyDB
    {
       private $db;
       public function __construct($connInfo)
       {
       }
       
       public function gueryForRows($sql)
       {
           return ['uid'=>333];
       }
    }
    
    class MyUser
    {
        public $mydb;
        //$dsn配置
        // 1 正向控制 public function __construct($dsn)
        public function __construct(MyDB $DB)
        {
            //1 正向实例化 以myUser控制MyDB
            //$this->mydb = new MyDB($dsn);
            //MyUser不会主动去实例化DB 控制顺序发生了反转 起到了解耦的目的
            $this->mydb = $DB;
        }
        
        public function getAllUsers():array {
            return $this->mydb->gueryForRows('select * from users');
        }
    }
    
    class ClassFactory
    {
        //容器   用来存放实例化后的类
        private static $container = [];
        
        public  static function set(String $name,callable  $func){
           self::$container[$name] = $func;
        }
        
        public static function getObject(string $name){
           if (isset(self::$container[$name])){
               //执行匿名函数
               return (self::$container[$name])();
           }
           return null;
        }
    }
    // 1 正向控制
    // $user = new MyUser('mysql:host=localhost');
    // 2 控制反转
    /*$db = new MyDB('mysql:host=localhost');
    //依赖注入 控制反转    向MyUser注入MyDB的实例
    $user = new MyUser($db);*/
    // 3 IoC容器
    // 3.1 往容器里注入mydb实例
    ClassFactory::set('mydb',function (){
        return new  MyDB('mysql:host=localhost');
    });
    // 3.2 往容器里注入mydb实例
    ClassFactory::set('my_user',function (){
        return new MyUser(ClassFactory::getObject('mydb'));
    });
    //3.3获取user实例
    $user = ClassFactory::getObject('my_user');
    
    $list = $user->getAllUsers();
    var_dump($list);

    IoC容器:为了让我们的代码更具维护性,把注入这个过程隐藏起来,放到了一个专门的“容器”里面管理

     在swoole出现之后,ClassFactory可以常驻内存。

    3 第三方DI库3.0

    安装

     composer require php-di/php-di

    3.1 使用方式一:简单使用(手工方式)不推荐

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    class MyDB
    {
       private $db;
       public function __construct($connInfo)
       {
       }
       
       public function gueryForRows($sql)
       {
           return ['uid'=>444];
       }
    }
    
    class MyUser
    {
        public $mydb;
        //$dsn配置
        // 1 正向控制 public function __construct($dsn)
        public function __construct(MyDB $DB)
        {
            //1 正向实例化 以myUser控制MyDB
            //$this->mydb = new MyDB($dsn);
            //MyUser不会主动去实例化DB 控制顺序发生了反转 起到了解耦的目的
            $this->mydb = $DB;
        }
        
        public function getAllUsers():array {
            return $this->mydb->gueryForRows('select * from users');
        }
    }
    
    /*class ClassFactory
    {
        //容器   用来存放实例化后的类
        private static $container = [];
        
        public  static function set(String $name,callable  $func){
           self::$container[$name] = $func;
        }
        
        public static function getObject(string $name){
           if (isset(self::$container[$name])){
               //执行匿名函数
               return (self::$container[$name])();
           }
           return null;
        }
    }*/
    
    // 1 正向控制
    // $user = new MyUser('mysql:host=localhost');
    // 2 控制反转
    /*$db = new MyDB('mysql:host=localhost');
    //依赖注入 控制反转    向MyUser注入MyDB的实例
    $user = new MyUser($db);*/
    // 3 IoC容器
    // 3.1 往容器里注入mydb实例
    /*ClassFactory::set('mydb',function (){
        return new  MyDB('mysql:host=localhost');
    });
    // 3.2 往容器里注入mydb实例
    ClassFactory::set('my_user',function (){
        return new MyUser(ClassFactory::getObject('mydb'));
    });
    //3.3获取user实例
    $user = ClassFactory::getObject('my_user');*/
    
    //4 使用DI组件
    $container = new DIContainer();
    
    $container->set('mydb',function (){
        return new  MyDB('mysql:host=localhost');
    });
    $container->set('my_user',function (DIContainer $c){
        return new MyUser($c->get('mydb'));
    });
    $user = $container->get('my_user');
    
    $list = $user->getAllUsers();
    var_dump($list);

    3.2 使用方式二:配置的方法加载类(推荐

    D:seckillproapp estMyDB.php

    <?php
    /**
     * Created by PhpStorm.
     * User: SUN
     * Date: 2021/11/12
     * Time: 23:24
     */
    
    namespace App	est;
    
    
    class MyDB
    {
        private $db;
        public function __construct($connInfo)
        {
        }
        
        public function gueryForRows($sql)
        {
            return ['uid'=>555];
        }
    }
    View Code

    D:seckillproapp estMyUser.php

    <?php
    /**
     * Created by PhpStorm.
     * User: SUN
     * Date: 2021/11/12
     * Time: 23:25
     */
    
    namespace App	est;
    
    
    class MyUser
    {
        public $mydb;
        //$dsn配置
        // 1 正向控制 public function __construct($dsn)
        public function __construct(MyDB $DB)
        {
            //1 正向实例化 以myUser控制MyDB
            //$this->mydb = new MyDB($dsn);
            //MyUser不会主动去实例化DB 控制顺序发生了反转 起到了解耦的目的
            $this->mydb = $DB;
        }
        
        public function getAllUsers():array {
            return $this->mydb->gueryForRows('select * from users');
        }
    }
    View Code

    D:seckillproapp esteans.php

    <?php
    namespace App	est;
    return [
      
      MyDB::class=>function (){
          return new   MyDB('mysql:host=localhost');
      },
        // my_user是我起的名,最好用   MyUser::class更规范化
    /*  'my_user'=>function (DIContainer $c){
          return new MyUser($c->get(mydb));
      },*/
      MyUser::class =>function (DIContainer $c){
          return new MyUser($c->get(MyDB::class));
      }
    ];

    D:seckillpro est.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    
    $builder = new DIContainerBuilder();
    //扫描所有的配置
    $builder->addDefinitions(__DIR__."/app/test/beans.php");
    $container = $builder->build();
    
    $user = $container->get(App	estMyUser::class);
    //echo   App	estMyUser::class.'------';//App	estMyUser
    $list = $user->getAllUsers();
    
    var_dump($list);
  • 相关阅读:
    置换笔记
    7.23
    Conveyor Belts
    CF #134 A~D
    Blocks && Fixing the Great wall
    Kakuro
    Deadlock Detection
    关于KeyFile的破解,含注册机源代码
    BMP位图之代码实现
    BMP位图之8位位图(三)
  • 原文地址:https://www.cnblogs.com/polax/p/15450154.html
Copyright © 2020-2023  润新知