美文网首页PHP经验分享PHP开发
浅析【IOC思想】(及Laravel实例应用)

浅析【IOC思想】(及Laravel实例应用)

作者: Bryanz | 来源:发表于2022-01-27 11:32 被阅读0次

    <输入的最好方式就是输出>,本着学习的态度表达一下自己浅显的理解。IOC(Inversion of Control),即控制反转,是面向对象中的一种设计原则。下面我将简单介绍IOC的作用实现原理,最后用具体的示例应用来帮助加深理解。

    1、IOC的作用

    IOC可以作为依赖对象统一管理者,从而降低代码的耦合性,提升程序的可维护性。

    2、实现原理

    IOC作为管理依赖的容器,涉及的相关技术是反射依赖注入
    下面将简单介绍PHP反射依赖注入

    • PHP反射
      简单概括就是对象的自省能力,对象通过反射获取其类的信息。
      示例代码:
    $node = new LinkNode();//实例化对象
    $nodeClass = new ReflectionClass($node);//通过对象获取其反射类
    $properties = $nodeClass->getProperties();//获取类的所有属性
    $methods = $nodeClass->getMethods();//获取类的所有方法
    
    • 依赖注入
      DI(dependency injection),即依赖注入,它是IOC的实现方式之一。下面将介绍PHP-DI相关原理(参考文档:https://php-di.org/doc/getting-started.html),以下是文档部分内容:
      1-php-di

    上图代码块介绍了依赖注入的作用,例子中UserManager类需要依赖Mailer类。通过注入的方式可避免手动实例化依赖对象,即调用UserManager时可以不用手动实例化依赖对象。

    标红的两块则是IOC容器实现依赖注入的技术,autowiring(自动装载)PHP's Reflection classes(PHP反射类)。autowiring可以扫描代码找到类的构造函数所需要的参数是什么(本例中是Mailer对象),php-di通过php反射类即可找到Mailer类并实例化对象。php反射类前面已经介绍过了,下面介绍下autowiring的原理。

    2-autowiring

    上图第一个红框表明,容器可以通过自动装载自动创建和注入依赖;第二个红框表示注入的过程等同于先实例化对象,再传递给构造函数的参数。另外文档还指出,构造函数的参数必须要有类型提示才能实现注入。
    php-di注入的方式其实不止autowiring这一种,总共有三种:autowiring(自动装载)、annotation(注解)、PHP definitions(PHP定义),感兴趣的小伙伴可以自行查阅文档相关内容。

    总结:IOC容器通过依赖注入的方式帮我们管理类的依赖关系,而不需要我们手动去管理依赖(实例化依赖对象)。本文的php依赖注入利用php反射找到依赖信息,autowiring自动加载实现构造参数的注入。

    3、示例应用(Laravel)

    纸上得来终觉浅,简单介绍完IOC容器的实现原理,现在以laravel为例具体实践应用一下,有助于加深理解。示例主要涉及两个层面,一个将类的依赖关系绑定到容器;另一个是从容器中解析类。
    Laravel官方文档
    英文版:https://laravel.com/docs/8.x/container#when-to-use-the-container
    中文版:https://learnku.com/docs/laravel/8.5/container/10365#120d42

    • IOC容器绑定类的依赖关系
      use App\Services\Transistor;
      use App\Services\PodcastParser;
      
      $this->app->bind(Transistor::class, function ($app) {
        return new Transistor($app->make(PodcastParser::class));
      });
      
      在这个例子中,Transistor是要绑定的类,它的依赖类是PodcastParser。如果 PodcastParser类自身也存在依赖,容器会根据它所绑定的依赖关系,递归地 解析相应的依赖。
      需要注意的是,如果PodcastParser没有在容器中绑定过,使用容器解析作为依赖会报错,即不能使用$app->make(PodcastParser::class),而应该使用new PodcastParser()
    • IOC容器的使用
      IOC容器的使用可以分为两步,依赖注入和make解析获取对象;
      1 依赖注入分为构造函数注入和set函数注入。
      2 Laravel中解析容器对象,可以使用助手函数从容器中解析获取:app()->make(PodcastParser::class);
      【另外,Laravel中的Facade门面类(静态代理类)本质也是通过容器解析对象;指定类要绑定别名至容器,同时对应的静态类要继承Facade类并重写getFacadeAccessor方法指定绑定别名,之后就能使用门面类实例对象了。】

    以上只是简单介绍了一下Laravel容器的依赖绑定和使用,方便理解IOC容器的运作过程

    实际上绑定过程还涉及到Laravel的核心<服务提供者>,我们需要在提供者的register注册方法中绑定相关依赖;绑定的类型也有很多种,可分为单例绑定(每次解析都是单例对象),接口绑定(自动解析注入的接口为指定实现类)等等,这边暂时不展开,感兴趣的小伙伴可以自行查阅文档。

    相关文章

      网友评论

        本文标题:浅析【IOC思想】(及Laravel实例应用)

        本文链接:https://www.haomeiwen.com/subject/cktohrtx.html