Laravel底层原理(四) —— 控制反转(IOC)

Royal
2022-01-14 / 0 评论 / 474 阅读 / 正在检测是否收录...
  • 什么是 IoC
    控制反转(Inversion of Control,缩写为 IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称 DI),还有一种方式叫 “依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。 — 维基百科
    简单说来,就是一个类把自己的的控制权交给另外一个对象,类间的依赖由这个对象去解决。依赖注入属于依赖的显示申明,而依赖查找则是通过查找来解决依赖。
  • Laravel 中的使用
    注入一个类:

    App::bind('foo', function($app)
    {
            return new FooBar;
    });

    这个例子的意思是创建一个别名为 foo 的类,使用时实际实例化的是 FooBar。

使用这个类的方法是:

$value = App::make('foo');

$value 实际上是 FooBar 对象。

如果希望使用单例模式来实例化类,那么使用:

App::singleton('foo', function()
{
        return new FooBar;
});

这样的话每次实例化后的都是同一个对象。
实现「控制反转」,有两种方式:

  1. Dependency Injection (DI) - 依赖注入
  2. Dependency Lookup - 依赖查找
  3. 哪些方面的「控制」被「反转」了?
    依赖对象的「获得」被反转了。
    Class A 中用到了 Class B 的对象 b,一般情况下,需要在 A 的代码中显式的 new 一个 B 的对象。采用依赖注入技术之后,A 的代码只需要定义一个私有的 B 对象,不需要直接 new 来获得这个对象,而是通过相关的 容器控制程序 来将 B 对象在外部 new 出来并注入到 A 类里的引用中。而具体获取的方法、对象被获取时的状态由 容器 来指定。
    假设我有一个 iPhone,我的 iPhone 依赖充电器才能充电。

    class iPhone
    {
        // 电量
        private $power;
    
        // 充电
        public function charge()
        {
        }
    }

    我还有个苹果原装充电器:

    class AppleCharger
    {
        public function charge()
        {
            return 100;
        }
    }

    在以前,iPhone 内部「控制」着只能用哪一款充电器:

    class iPhone
    {
        // 电量
        private $power;
    
        // 充电,只能用原装的充电器
        public function charge()
        {
            $charger = new AppleCharger;
            $this->power = $charger->charge();
        }
    }
    // 充电
    $iphone = new iPhone;
    $iphone->charge();

    使用依赖注入之后,我来决定给 iPhone 用哪一款充电器:

    class iPhone
    {
        private $power;
        private $charger;
    
        // 依赖注入充电器,╮(╯▽╰)╭哎算了只要是充电器就行
        public function __construct(Charger $charger)
        {
            $this->charger = $charger;
        }
    
        // 充电
        public function charge()
        {
            $this->power = $this->charger->charge();
        }
    }
    interface Charger
    {
        public function charge();
    }
    // Laravel 容器
    use Illuminate\Container\Container;
    $container = Container::getInstance();
    
    // 给它一个原装充电器:
    $container->bind(Charger::class, AppleCharger::class);
    
    // 或者给它其它充电器
    $container->bind(Charger::class, OtherCharger::class);
    
    // 充电
    $iphone = $container->make(iPhone::class);
    $iphone->charger();

    可见,使用依赖注入之后,控制权「反转」了,由外部来决定给它什么充电器 (依赖对象)。
    Laravel 管这个 容器控制程序 叫 Service Container (服务容器),它来控制着各种依赖的获取方法

0

评论

博主关闭了当前页面的评论