zoukankan      html  css  js  c++  java
  • 【看完就懂】Laravel 服务容器,IoC,DI 阅读笔记

    个人理解:

      容器 依赖注入(DI) 控制反转(IoC) 最终实现 
    通过容器来生成 类 类的依赖 通过 外部传入容器 来扩展和实现 类功能 在 类的内部通过统一方法调用 来使用不同的功能

    原文地址:https://learnku.com/articles/19195

    其他参考:https://www.insp.top/learn-laravel-container

    朋友推荐的资料:https://zhuanlan.zhihu.com/p/33492169

    容器:
      容器,字面上的理解就是装东西的东西.常见的变量 对象属性 等都可以算是容器.一个容器能够装什么.全部都取决于你对该容器的定义.当然,有这样一种容器,他存放的不是文本 数值 而是对象 对象的描述(类 接口) 或是提供对象的回调 通过这种容器 我们得以实现许多高级的功能 其中最长提到的就是 解耦 依赖注入(DI).
     
    Ioc 容器:
      Laravel 服务容器是一个用于管理类依赖和执行依赖注入的强大工具。服务容器就是工厂模式的升级版,对于传统的工厂模式来说,虽然解耦了对象和外部资源之间的关系,但是工厂和外部资源之间却存在了耦合,而服务容器在为对象创建了外部资源的同时,又与外部资源没有任何关系,这个就是ioc容器.
     
    依赖的产生:
      例如我们程序员开发程序就需要依赖与电脑 电脑又依赖于 显示屏 键盘 等 笔记本的显示屏和键盘 都是集成在一起的 导致了如果要调整依赖 换显示屏和键盘就需要拆电脑才可以更换 比较麻烦 但是如果是使用外接方式来扩展 只要符合相同规格 就可以很方便的 更换和扩展.
     
    依赖注入:
      只要不是由内部生产(比如初始化、构造函数 __construct 中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI)
     
    控制反转:
      控制反转意思是说将依赖类的控制权交出去,由主动变为被动

    <?php
        /*
            
         */
        //容器类
        class Container
        {
            protected $binds;
    
            protected $instances;
    
            public function bind($abstract, $concrete)
            {
    
                // $abstract 方法名称
                // var_dump($abstract);
                // $concrete 对象本体
                // var_dump($concrete);
                //判断是否来自于 Closure(闭包类) 接口 
                if ($concrete instanceof Closure) {
                    //是闭包放入 $binds
                    $this->binds[$abstract] = $concrete;
                } else {
                    //不是闭包放入 $instances
                    $this->instances[$abstract] = $concrete;
                }
    
                if($abstract == 'Computer'){
                    // var_dump($abstract);
                    // var_dump($concrete);
                    // 这里并没有接收到 $module 显然 $module 不是在这里用的
                    // var_dump($module);
                }
            }
    
            public function make($abstract, $parameters = [])
            {
                //这里判断 外部传入的对象是否存在 存在返回 外部传入的对象
                //用于判断是否是之前传入的闭包 不是闭包则返回 之前传入的对象
                if (isset($this->instances[$abstract])) {
                    return $this->instances[$abstract];
                }
    
                //不存在
                //array_unshift 在数组开头插入一个或多个单元
                //将对象$this 插入 $parameters 的头部 作为闭包类的 参一 这里做参数拼接
                array_unshift($parameters, $this);
    
                // var_dump($parameters);die;
                //调用 闭包方法 $abstract 传入 参数$parameters 
                //主要用于创建闭包 传入的对象
                return call_user_func_array($this->binds[$abstract], $parameters);
            }
        }
    
    
    
        //Computer类(测试用)
        class Computer{
            private $CommonBoard;
    
            public function __construct($obj)
            {
    
                //这里拿到了共用键盘对象
                $this->CommonBoard = $obj;
                echo '<hr>Computer中得到Board对象';
                var_dump($this->CommonBoard);
                echo '<hr>';
    
            }
    
    
            public function startingUp(){
                echo '<hr>Computer中使用CommonBoard对象';
    
                //调用CommonBoard 类中的test 方法
                var_dump($this->CommonBoard);
                $this->CommonBoard->test();
    
                echo '<hr>Hello world';
                echo '<hr>';
    
            }
    
        }
    
        //公用键盘类(测试用)
        class CommonBoard{
            public function __construct()
            {
                //公用的初始化设置
                echo '<hr>实例化CommonBoard对象<hr>';
            }
    
            //键盘类公用方法
            public function test(){
                echo '<hr>使用原有键盘功能<hr>';
            }
        }
    
        //ikbc键盘(测试用)
        class mechanicalKeyboard  extends CommonBoard{
            public function test(){
                echo '<hr>使用机械键盘';
                $this->lightUp();
                echo '<hr>';
            }
            //
            private function lightUp()
            {
                echo  '<br>开灯';
            }
        }
    
        $container = new Container;
    
        $container->bind('Board', function($container){
            return new CommonBoard;
        });
    
    
    
        //$container 即 array_unshift($parameters, $this); 这里存入的 
        //$module 后面调用出传入 
        //
        $container->bind('Computer',function($container,$module){
            // var_dump($container);
            // var_dump($module);
            // die;
            // 这里就可以传入 任意需要传入的对象 
            return new Computer($container->make($module));
        });
    
        //实例化 这里就拿到了一个 之前传入的公用键盘类的 Computer类(生成带有原有键盘的电脑)
        $computer = $container->make('Computer',['Board']);
    
        $computer->startingUp();
    
        $obj = new mechanicalKeyboard;
        //注册
        $container->bind('mechanicalKeyboard',$obj);
        //生成带有mechanicalKeyboard的电脑
        $computer = $container->make('Computer',['mechanicalKeyboard']);
    
        $computer->startingUp();
    
    
    ?>
  • 相关阅读:
    面试题总结(vue面试题)
    面试题总结(css面试题)
    设置div居中显示
    关于js中iframe 中 location.href的用法
    js判断是否在iframe中
    npm git 常用命令行 记录
    mongDB数据库 小白学习
    EJS 入门学习
    bower 基础认识
    gulp 粗粗学习 记录下
  • 原文地址:https://www.cnblogs.com/y734290209/p/10826735.html
Copyright © 2011-2022 走看看