lumen-ioc容器测试 (4)
问题二,这个其实也不算问题,就是写法上的优化,我们是不是每次都要传递第二个参数并且每次都要写一个闭包进去?
# class Container# 复制上面的代码 class Person{ public $name; } $container = new Container(); $container->bind('person' , function(){ return new Person(); },true);
我们来分析一下,实际上我已经知道了Person类,那么我们能不能想下面代码中的这么实现呢
... $container = new Container(); $container->bind('Person' , 'Person' , true); $container->bind('Person'); ...
接下来继续改进
class Container { private $bindings = []; private $instances = []; #这里是生成闭包的地方 public function getClosure($concrete) { return function() use($concrete) { return new $concrete; }; } public function bind($abstract , $concrete=null, $shared = false) { if (is_null($concrete)) { $concrete = $abstract; } # 如果$concrete 不是一个闭包生成一个闭包 if (!$concrete instanceof Closure) { $concrete = $this->getClosure($concrete); } $this->bindings[$abstract] = [ 'concrete' => $concrete, 'shared' => $shared ]; } public function make($abstract) { if (!isset($this->bindings[$abstract])) { return false; } if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } $object = $this->bindings[$abstract]['concrete'](); if($this->bindings[$abstract]['shared']) { $this->instances[$abstract] = $object; } return $object; } } class Person{ public $name; } # testing $container = new Container(); $container->bind('Person' , 'Person' , false); $p1 = $container->make('Person'); $p2 = $container->make('Person'); var_dump($p1 , $p2 , $p1 === $p2); $c1 = new Container(); $c1->bind('Person'); $p3 = $c1->make('Person'); $p4 = $c1->make('Person'); var_dump($p3 , $p4 , $p3 === $p4); $c2 = new Container(); $c2->bind('Person','Person', true); $p5 = $c2->make('Person'); $p6 = $c2->make('Person'); var_dump($p5 , $p6 , $p5 === $p6);
入门我们自己写这个container大部门人会在make里去判断是否是一个闭包,写完就不再优化了...