zoukankan      html  css  js  c++  java
  • 简单理解laravel中的Ioc控制反转(依赖注入)

    由于laravel中的Ioc还考虑了参数为字符串,参数有默认值等众多情况,所以总体看起来比较复杂。

    但总之,其目的是为了解决不同类之间的依赖关系。当然工厂方法某种程度上也能解决这个问题,只是,Ioc来的更优雅。

    这里提供一个删节版

    <?php 
    /**
    * 
    */
    class Container
    {
      protected $bindings = [];
    
      public function bind($abstract, $concrete)
      {
      $this->bindings[$abstract]['concrete'] = $concrete;
      }
    
      public function make($abstract)
      {
        $concrete = $this->getConcrete($abstract);
        return $this->build($abstract, $concrete);
      }
    
      public function getConcrete($abstract)
      {
        if(isset($this->bindings[$abstract])) {
          return $this->bindings[$abstract]['concrete'];
        }
      }
    
      public function build($abstract, $concrete)
      {
        $reflector = new ReflectionClass($concrete);
        if(! $reflector->isInstantiable()) {
          return '无法实例化';
        }
        $constructor = $reflector->getConstructor();
        if(is_null($constructor)) {
          return new $concrete;
        }
        $parameters = $constructor->getParameters();
    
        $instances = $this->getDependencies($abstract, $parameters);
        return $reflector->newInstanceArgs($instances);
      }
    
      public function getDependencies($abstract, $parameters)
      {
        $dependencies = [];
        foreach ($parameters as $parameter) {
          $dependency = $parameter->getClass();
          if(is_null($dependency)) {
            $dependencies[] = null;
          }
          $dependencies[] = $this->make($dependency->name);
        }
        return $dependencies;
      }
    
    }
    
    /**
    * 
    */
    abstract class Tool
    {
      abstract public function go();
    }
    
    /**
    * 
    */
    class Train extends Tool
    {
      public function go()
      {
        echo "method go froom class Train";
      }
    }
    
    /**
    * 
    */
    class Tour
    {
      protected $tool;
    
      function __construct(Tool $tool)
      {
        $this->tool = $tool;
      }
    
      public function visit()
      {
        $this->tool->go();
      }
    }
    
    $container = new Container();
    $container->bind('Tool', 'Train');
    $container->bind('tour', 'Tour');
    $tour = $container->make('tour');
    $tour->visit();
    

      

    输出:method go froom class Train

    大功告成,哈哈

    当然啦,这里的删节版只是便于理解Ioc的运行原理,并没有对每种情况都考虑周全,比如,若构造函数中需要传入的参数并不是对象,只是单纯的字符串,就会接收到null,还有不支持单例模式等问题。

  • 相关阅读:
    Python+request+unittest实现接口测试框架集成实例
    真正解决Jenkins安装插件总是报错的问题(网上查的解决方案都无效)
    Rancher 2.2.2
    Rancher管理k8s集群
    清理cosbench工具所占用磁盘空间的小脚本
    一个检查本机和远程机器的根目录所在磁盘的剩余空间的bash小脚本
    当df命令hang住了, 怎么办?
    OpenCV操作像素的几种方法(单个像素|操作多像素|遍历像素)
    OpenCV-颜色通道的分离、合并(转)
    ImageMagick 提取四通道png图片的alpha及magick使用
  • 原文地址:https://www.cnblogs.com/buerr/p/6704269.html
Copyright © 2011-2022 走看看