PHP 控制反转(IoC) 和 依赖注入(DI)

简单实现一个代码依赖:

<?php

class iocA
{
    public $b;
    public $c;

    public function A()
    {
        //TODO
    }

    public function Method()
    {
        $this->b = new iocB();
        $this->c = new iocC();

        $this->b->Method();
        $this->c->Method();
    }
}

class iocB
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        echo 'b';
    }
}

class iocC
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        //TODO
        echo 'c';
    }
}

$a = new iocA();
$a->Method();

上边的代码实现了 iocA 类依赖 iocB 类和 iocC 类。
如果在开发过程中,需要对 iocB 类或者ioc C 类进行修改,,一旦涉及到函数名称的改变,或者函数参数数量的变动,或者整个类结构的变化,我们也需要对 iocA 类进行调整,iocA 类的独立性就丧失了,这在开发中和不方便,代码复杂,耦合度不尽人意,这样会造成“牵一发动全身”,解决这个问题就需要用到 控制翻转(IOC)。

控制反转(IOC)是一种思想,依赖注入(DI)是实施这种思想的方法。

依赖注入的实现

第一种:构造器注入

<?php

class iocA
{
    public $b;
    public $c;

    public function __construct($iocB, $iocC)
    {
        $this->b = $iocB;
        $this->c = $iocC;
    }

    public function Method()
    {
        $this->b->Method();
        $this->c->Method();
    }
}

class iocB
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        echo 'b';
    }
}

class iocC
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        //TODO
        echo 'c';
    }
}

$a = new iocA(new iocB(), new iocC());
$a->Method();

iocA 类的构造器依赖 iocB 类和 iocC 类,通过构造器的参数传入,至少实现了一点,就是 iocB 类对象 b 和 iocC 类对象 c 的创建都移至了 iocA 类外,所以一旦 iocB 类和 iocC 类发生改动,iocA 类无需做修改,只要在相对应类里改就可以了。

第二种:工厂模式注入

<?php

class Factory
{
    public function Factory()
    {
        //TODO
    }

    public function create($s)
    {
        switch ($s) {
            case 'B':
            {
                return new iocB();
                break;
            }
            case 'C':
            {
                return new iocC();
                break;
            }
            default:
            {
                return null;
                break;
            }
        }
    }
}

class iocA
{
    public $b;
    public $c;

    public function __construct()
    {
        //TODO
    }

    public function Method()
    {
        $factory = new Factory();
        $this->b = $factory->create('B');
        $this->c = $factory->create('C');

        $this->b->Method();
        $this->c->Method();
    }
}

class iocB
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        echo 'b';
    }
}

class iocC
{
    public function C()
    {
        //TODO
    }

    public function Method()
    {
        //TODO
        echo 'c';
    }
}

$a = new iocA();
$a->Method();

其实已经解耦了一小部分,至少如果 iocB 类和 iocC 类的构造函数要是发生变化,

比如修改函数参数等,我们只需要改 Factory 类就可以了。

抽象不应该依赖于细节,细节应该依赖于抽象。

本作品采用《CC 协议》,转载必须注明作者和本文链接
✍️博客文章皆为网络收藏整理,作书签使用,方便后期查阅。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!