看了篇讲解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
)