• Ioc实现的基本机制


    <?php
    
    interface KeyBoard{
        public function make();
    }
    
    interface Mouse{
        public function make();
    }
    
    class MechanicalKeyboard implements KeyBoard
    {
        public function make(){
            echo '机械键盘正在work';
        }
    }
    
    class CommonKeyboard implements KeyBoard
    {
        public function make(){
            echo '普通键盘正在work';
        }
    }
    
    class CommonMouse implements Mouse
    {
        public function make(){
            echo '普通鼠标正在work';
        }
    }
    
    
    class Computer
    {
        protected $keyBoard;
    
        protected $mouse;
    
        public function __construct(KeyBoard $keyBoard,Mouse $mouse)
        {
            $this->keyBoard = $keyBoard;
    
            $this->keyBoard->make();
    
            $this->mouse = $mouse;
    
            $this->mouse->make();
        }
    }
    
    class Container
    {
        private $binds;
    
        //将接口和类名保存到binds中
        public function bind($contract,$concrete)
        {
            $this->binds[$contract] = $concrete;
        }
    
        //获取到指定方法的注入参数,默认方法是采用__construct进行注入
        public function methodBindParams($className)
        {
            $reflect = new Reflect($className,'__construct');
    
            return $reflect->bindParamsToMethod();
        }
    
        //实例化类
        public function make($className)
        {
            //获取需要实例化类所需要的必要参数
            $methodBindParams = $this->methodBindParams($className);
    
            //实例化类反射类
            $reflect = new Reflect($className,'__construct');
    
            //实例化类,插入实例化所需要的参数和参数接口对应的类
            return $reflect->make($this->binds,$methodBindParams);
        }
    }
    
    class Reflect
    {
        private $className;
    
        private $methodName;
    
        public function __construct($className,$methodName)
        {
            $this->className = $className;
    
            $this->methodName = $methodName;
        }
    
        public function bindParamsToMethod()
        {
            $params = [];
    
            //获取到类的方法信息
            $method = new ReflectionMethod($this->className,$this->methodName);
    
            //将类方法参数信息保存到params中
            foreach ($method->getParameters() as $param){
                $params[] = [
                    //参数名称
                    $param->name,
                    //参数是哪个类型
                    $param->getClass()->name
                ];
            }
    
            //返回这个类--》方法的参数
            return [$this->className => $params];
        }
    
        public function make($bind,$methodBindParams)
        {
            $args = [];
    
            //遍历类-》参数列表
            foreach ($methodBindParams as $className => $params){
                //遍历参数列表
                foreach ($params as $param){
                    //获取到参数名和参数类型(是哪个接口)
                    list($paramName,$paramType) = $param;
    
                    //实例化对应接口的实现的类
                    $paramName = new $bind[$paramType]();
    
                    //将实例化后的类放到args列表中
                    array_push($args,$paramName);
                }
            }
    
            //实例化反射
            $reflectionClass = new ReflectionClass($this->className);
    
            //从给定参数生成一个实例
            return $reflectionClass->newInstanceArgs($args);
        }
    }
    
    $container = new Container();
    
    $container->bind('KeyBoard','CommonKeyBoard');
    $container->bind('Mouse','CommonMouse');
    
    $container->make('Computer');
  • 相关阅读:
    什么叫继承?
    两类交换元素使序列有序 求最少交换次数的题
    如何理解汉诺塔
    求给出第 K个 N位二进制数,该二进制数不得有相邻的“1”
    7/26 CSU-ACM2018暑期训练3-递归&递推-选讲
    平面分割
    递推算法之平面分割问题总结
    UTC时间
    7/25 CSU-ACM2018暑假集训比赛1
    洛谷 P1824 进击的奶牛【二分答案/类似青蛙过河】
  • 原文地址:https://www.cnblogs.com/ywjcqq/p/14078684.html
Copyright © 2020-2023  润新知