zoukankan      html  css  js  c++  java
  • laravel框架中容器类简化代码-摘自某书

      1 <?php 
      2 
      3 //容器类装实例或提供实例的回调函数
      4 class Container {
      5 
      6     protected $bindings = [];
      7 
      8     //绑定接口和生成相应实例的回调函数
      9     public function bind($abstract, $concrete=null, $shared=false) {
     10         
     11         //如果提供的参数不是回调函数,则产生默认的回调函数
     12         if(!$concrete instanceof Closure) {
     13             $concrete = $this->getClosure($abstract, $concrete);
     14         }
     15         
     16         $this->bindings[$abstract] = compact('concrete', 'shared');
     17     }
     18 
     19     //默认生成实例的回调函数
     20     protected function getClosure($abstract, $concrete) {
     21         
     22         return function($c) use ($abstract, $concrete) {
     23             $method = ($abstract == $concrete) ? 'build' : 'make';
     24             return $c->$method($concrete);
     25         };
     26         
     27     }
     28 
     29     public function make($abstract) {
     30         $concrete = $this->getConcrete($abstract);
     31 
     32         if($this->isBuildable($concrete, $abstract)) {
     33             $object = $this->build($concrete);
     34         } else {
     35             $object = $this->make($concrete);
     36         }
     37         
     38         return $object;
     39     }
     40 
     41     protected function isBuildable($concrete, $abstract) {
     42         return $concrete === $abstract || $concrete instanceof Closure;
     43     }
     44 
     45     //获取绑定的回调函数
     46     protected function getConcrete($abstract) {
     47         if(!isset($this->bindings[$abstract])) {
     48             return $abstract;
     49         }
     50 
     51         return $this->bindings[$abstract]['concrete'];
     52     }
     53 
     54     //实例化对象
     55     public function build($concrete) {
     56 
     57         if($concrete instanceof Closure) {
     58             return $concrete($this);
     59         }
     60 
     61         $reflector = new ReflectionClass($concrete);
     62         if(!$reflector->isInstantiable()) {
     63             echo $message = "Target [$concrete] is not instantiable";
     64         }
     65 
     66         $constructor = $reflector->getConstructor();
     67         if(is_null($constructor)) {
     68             return new $concrete;
     69         }
     70 
     71         $dependencies = $constructor->getParameters();
     72         $instances = $this->getDependencies($dependencies);
     73 
     74         return $reflector->newInstanceArgs($instances);
     75     }
     76 
     77     //解决通过反射机制实例化对象时的依赖
     78     protected function getDependencies($parameters) {
     79         $dependencies = [];
     80         foreach($parameters as $parameter) {
     81             $dependency = $parameter->getClass();
     82             if(is_null($dependency)) {
     83                 $dependencies[] = NULL;
     84             } else {
     85                 $dependencies[] = $this->resolveClass($parameter);
     86             }
     87         }
     88 
     89         return (array)$dependencies;
     90     }
     91 
     92     protected function resolveClass(ReflectionParameter $parameter) {
     93         return $this->make($parameter->getClass()->name);
     94     }
     95 
     96 }
     97 
     98 
     99 class Traveller {
    100 
    101     protected $trafficTool;
    102 
    103     public function __construct(Visit $trafficTool) {
    104         $this->trafficTool = $trafficTool;
    105     }
    106 
    107     public function visitTibet() {
    108         $this->trafficTool->go();
    109     }
    110 
    111 }
    112 
    113 interface Visit {
    114     public function go();
    115 }
    116 
    117 class Train implements Visit {
    118 
    119     public function go() {
    120         echo "go to Tibet by train !!!";
    121     }
    122     
    123 }
    124 
    125 $app = new Container();
    126 $app->bind("Visit", "Train");
    127 $app->bind("traveller", "Traveller");
    128 
    129 
    130 $tra = $app->make("traveller");
    131 $tra->visitTibet();
  • 相关阅读:
    我对IOC控制反转,依赖注入原理的理解
    .net带事件的对象BinaryFormatter 序列化失败
    (维权成功,链接已经被删除了)如何防止自己的原创文章被垃圾站IT165采集和盗用
    浅谈.net多线程机制
    给现下流行的打车软件的一点小建议
    C#应用MemoryStream提高File读取速度
    微软真的要抛弃Silverlight了吗?
    C# File.Copy 实现磁盘间文件备份
    遮罩層 日曆效果
    GridView導出Excel
  • 原文地址:https://www.cnblogs.com/dongruiha/p/6168621.html
Copyright © 2011-2022 走看看