21 05 2020

依赖注入模式

模式定义

依赖注入模式(Dependency Injection),是控制反转(Inversion of Control)的一种实现方式。要实现控制反转,通常的解决方案是将创建被调用者实例的工作交由 IoC 容器来完成,然后在调用者中注入被调用者(通过构造器 / 方法注入实现),这样我们就实现了调用者与被调用者的解耦,该过程被称为依赖注入。


依赖注入模式的优势

调用者与被调用者的解耦  


代码示例

DependencyInjection\AbstractConfig.class.php
<?php

namespace DependencyInjection;

abstract class AbstractConfig
{
    protected $storage;

    public function __construct($storage)
    {
        $this->storage = $storage;
    }
}


DependencyInjection\Parameters.class.php
<?php

namespace DependencyInjection;

interface Parameters
{
    public function get($key);

    public function set($key, $value);
}


DependencyInjection\ArrayConfig.class.php
<?php

namespace DependencyInjection;

class ArrayConfig extends AbstractConfig implements Parameters
{

    public function get($key, $default = null)
    {
        if(isset($this->storage[$key])) {
            return $this->storage[$key];
        }
        return $default;
    }

    public function set($key, $value)
    {
        $this->storage[$key] = $value;
    }
}


DependencyInjection\Connection.class.php
<?php

namespace DependencyInjection;

class Connection
{
    protected $configuration;

    protected $host;

    public function __construct(Parameters $config)
    {
        $this->configuration = $config;
    }

    public function connect()
    {
        $host = $this->configuration->get('host');

        $this->host = $host;
    }

    public function getHost()
    {
        return $this->host;
    }
}


DependencyInjection\DependencyInjectionTest.php
<?php
spl_autoload_register(function ($className){
    $className = str_replace('\\', '/', $className);
    include $className.".class.php";
});

use DependencyInjection\ArrayConfig;
use DependencyInjection\Connection;

$source = array('host' => 'github.com');
$config = new ArrayConfig($source);

$connection = new Connection($config);
$connection->connect();

echo $connection->getHost();
echo "\n";


测试示例:

php DependencyInjection\DependencyInjectionTest.php 

输出:
github.com


总结

依赖注入模式需要在调用者外部完成容器创建以及容器中接口与实现类的运行时绑定工作,在 Laravel 中该容器就是服务容器,而接口与实现类的运行时绑定则在服务提供者中完成。此外,除了在调用者的构造函数中进行依赖注入外,还可以通过在调用者的方法中进行依赖注入。




代码地址:https://github.com/798256478/design-patterns/tree/master/DependencyInjection