美文网首页
Ioc容器实现

Ioc容器实现

作者: 谁的忧伤 | 来源:发表于2018-08-23 11:19 被阅读0次

    看了篇讲解laravel Ioc容器的文章,自己照着文章实践了下,注释部分是自己的理解

    interface SuperModuleInterface{
        public function activate();
    }
    
    class XPower implements SuperModuleInterface {
        
        protected $range;
        protected $cd;
        
        public function __construct($range=0,$cd=0) {
            $this->range = $range;
            $this->cd = $cd;
        }
        
        public function activate(){ print_r($this);}
    }
    
    class Fly implements SuperModuleInterface {
      
        protected $height;
        protected $times;
        
        public function __construct($height=0,$times=0) {
            $this->height = $height;
            $this->times = $times;
        }
        
        public function activate(){ print_r($this);}
    }
    
    class SuperModuleFactory{
        public function makeModule($moduleName,$options){
            switch($moduleName){
                case 'fly': return new Fly($options[0],$options[1]);
                case 'xpower': return new XPower($options[0],$options[1]);
            }
        }
    }
    
    
    class Container{
    
        protected $binds;
        protected $instances;
    
        public function bind($abstract,$concrete){
            if($concrete instanceof Closure){
                $this->binds[$abstract]=$concrete;
            }else{
                $this->instances[$abstract]=$concrete;
            }
        }
        
        public function make($abstract,$parmeters=[]){
            if(isset($this->instances[$abstract])){
                return $this->instances[$abstract];
            }
            
            array_unshift($parmeters,$this);
            
            #调用回调函数,并把自身作为第一个参数传入
            return call_user_func_array($this->binds[$abstract],$parmeters);
            
        }
        
    }
    
    class Superman{
    
        protected $power;
        
        /**
         * 第三代构造器-依赖注入
         * @param SuperModuleInterface $module 超能力模块
         */
        public function __construct(SuperModuleInterface $module) {
            $this->power=$module;
        }
        
        /**
         * 第二代构造器-依赖工厂
         * @param $modules
         */
        //public function __construct($modules) {
        //    $factory=new SuperModuleFactory();
        //    foreach($modules as $moduleName =>$options){
        //        $this->power[]=$factory->makeModule($moduleName,$options);
        //    }
        //
        //}
        
        /**
         * 第一代构造器-依赖具体实现类
         */
        //public function __construct() {
        //    $this->power[]=new XPower(100,11);
        //    $this->power[]=new Fly(10000,3600);
        //}
        
        public function attack(){
            $powers=is_array($this->power)?$this->power:array($this->power);
            foreach($powers as $p){
                $p->activate();
            }
        }
    }
    
    $container=new Container();
    
    #此处这个写保证每次注入的都是一个新的对象
    #如果写成    $container->bind('XPower',new XPower());
    #那么每次注入的都将是同一个对象,即注入的对象在各个实例中共享[传参是对象时传递的是引用,不是复制]
    $container->bind('XPower',function($container,$range,$cd){
        return new XPower($range,$cd);
    });
    
    $container->bind('Fly',function($container,$height,$times){
        return new Fly($height,$times);
    });
    
    $container->bind('Superman',function($container,$moduleName, ...$arg){
        return new Superman($container->make($moduleName,$arg));
    });
    
    $superman_1=$container->make('Superman',['XPower',1,2]);
    $superman_2=$container->make('Superman',['Fly',5,6]);
    
    echo '<pre>';
    $superman_1->attack();
    echo PHP_EOL;
    $superman_2->attack();
    

    执行结果:

    XPower Object
    (
        [range:protected] => 1
        [cd:protected] => 2
    )
    
    Fly Object
    (
        [height:protected] => 5
        [times:protected] => 6
    )
    

    相关文章

      网友评论

          本文标题:Ioc容器实现

          本文链接:https://www.haomeiwen.com/subject/beypiftx.html