• 简单理解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,还有不支持单例模式等问题。

  • 相关阅读:
    Linux 切换用户
    Java之.jdk安装-Linux
    Java之.jdk安装-Windows
    java注解生成xml和包含CDATA问题
    Spring学习—生成图片验证码
    java学习——java按值传递和按址传递
    温水中被煮熟的程序员-人生的思考
    mysql操作sql的小技巧
    java的classLoader分析与jettty的WebAppClassLoader
    深入Spring:自定义事务管理
  • 原文地址:https://www.cnblogs.com/buerr/p/6704269.html
Copyright © 2020-2023  润新知