什么是IOC容器

控制反转(IOC)

想知道什么叫控制反转就先明白什么叫控制不反转(实在想不出应该怎么叫啦,明白意思就好,不必纠结用词雅不雅)我们举个例子看一下,假如我们想要生产一部手机,每款手机只存在系统的差异

class Ios{
	public function getSystemMark(){
		echo "This is a ios Phone";
	}
}

class Android{
	public function getSystemMark(){
		echo "This is a android Phone";
	}
}

class Phone{
	public function make(){
		$ios = new Ios();
		$ios->getSystemMark();
	}
}

//产一部苹果手机
$ios_phone = new Phone();
$ios_phone->make();

对于上面这种当实例化phone类并且调用其中make方法时 对象会主动的在类的内部获取所需要的外部资源(这里指由Ios类实例化出来的对象),这种情况就叫做控制不反转

  • 对于这种情况下有一种弊端就是当我们想要生产一部android手机时需要修改phone类中的make方法这样的话就是的代码的耦合率更加的大。这样的话如果想要生产多种系统的手机的话岂不是很麻烦,这个问题要怎么解决呢??接在来就是控制反转登场的时刻啦!看改良后的代码
  • interface System{
    	public function getSystemMark();
    }
    
    class Ios implements System{
    	public function getSystemMark(){
    		echo "This is a ios Phone";
    	}
    }
    
    class Android implements System{
    	public function getSystemMark(){
    		echo "This is a android Phone";
    	}
    }
    
    class Phone{
    	protected $system;
    	public function __construct(System $system){
    		$this->system = $system;
    	}
    
    	public function make(){
    		$this->system->getSystemMark();
    	}
    }
    
    $ios = new Ios();
    $ios_phome = new Phone($ios);
    $ios_phome->make();
    
    $android = new Android();
    $android_phone = new Phone($android);
    $android_phone->make();

     

  • 现在我们在实例化phone类的时候就不用在make的内部去实例化相应的系统类啦!这种由外部提供对象所需资源(这里指 系统对象)的情况叫做控制反转,实现控制反转的方式叫做依赖注入(DI)
  • phone类实例化的对象调用make方法时,make方法的实现依赖于 系统类所实例化得到的对象,但是这种对象不是有phone类内部实例化获得的,而是在外部实例化伙的然后通过构造方法传入进对象的内部的,这种方式叫做依赖注入。
  • 好啦!知道了什么叫做控制反转、依赖注入后让我们来看看怎么把代码再优化一下。上面的代码虽然我们实现了IOC和DI,但是当我们获取一个手机时还要自己去手动实例化 ios android的类然后再实例化phone,这么做太不智能啦!但是我们怎么来让它更好一些呢!这时候我们使用IOC容器来实现就可以啦,下面代码:

  • interface System{
    	public function getSystemMark();
    }
    
    class Ios implements System{
    	public function getSystemMark(){
    		echo "This is a ios Phone";
    	}
    }
    
    class Android implements System{
    	public function getSystemMark(){
    		echo "This is a android Phone";
    	}
    }
    
    class Phone{
    	protected $system;
    	public function __construct(System $system){
    		$this->system = $system;
    	}
    
    	public function make(){
    		$this->system->getSystemMark();
    	}
    }
    
    class Container{
    	private $instances;
    	private $binds;
    
    	public function binds($abstract,$concrete){
    		if($concrete instanceof Closure){
    			$this->binds[$abstract] = $concrete;
    		}else{
    			$this->instances[$abstract] = $concrete;
    		}
    		
    	}
    
    	public function make($abstract,$params = []){
    		if(isset($this->instances[$abstract])){
    			return $this->instances[$abstract];
    		}
    
    		if($params){
    			$params = [$params];
    			array_unshift($params, $this);
    			return call_user_func_array($this->binds[$abstract],$params);
    		}else{
    			return call_user_func($this->binds[$abstract]);
    		}
    		
    	}
    
    }
    
    $container = new Container();
    $container->binds("phone",function($container,$system){
    	return new Phone($container->make($system));
    });
    
    $container->binds("ios",function(){
    	return new Ios();
    });
    
    $container->binds("android",function(){
    	return new Android();
    });
    
    $ios_phone = $container->make("phone","ios");
    $android_phone = $container->make("phone","android");
    
    $ios_phone->make();
    $android_phone->make();

    ok!ioc容器的简单实现就完成啦!更高级的IOC容器要使用类的反射来做

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值