IoC(控制反轉)的理解筆記

Neymar發表於2019-06-19

閱讀laravel文件時看到服務容器時無法理解,於是從論壇找到一篇不錯的文章-- Laravel 學習筆記 —— 神奇的服務容器,PHP基礎不是很好,花了很長時間才理解。整理了一下自己的傻瓜式理解過程。

範例程式碼:

<?php
class Superman
{
    public $module;
    public function __construct(SuperModuleInterface $module)
    {
        $this->module = $module;
    }
}
interface SuperModuleInterface
{
    public function activate(array $target = []);
}
class XPower implements SuperModuleInterface
{
    public function activate(array $target = [])
    {
        echo "X-超能量";
    }
}
class UltraBomb implements SuperModuleInterface
{
    public function activate(array $target = [])
    {
        echo "終極炸彈";
    }
}
class Container
{
    protected $binds;
    protected $instances;
    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }
    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }
        array_unshift($parameters, $this);
        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}

// 建立一個容器(後面稱作超級工廠)
$container = new Container;
// 向該 超級工廠 新增 超人 的生產指令碼
$container->bind('superman', function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});
// 向該 超級工廠 新增 超能力模組 的生產指令碼
$container->bind('xpower', function($container) {
    return new XPower;
});
 同上
$container->bind('ultrabomb', function($container) {
    return new UltraBomb;
});
// 開始啟動生產
$superman_1 = $container->make('superman', ['xpower']);
$superman_2 = $container->make('superman', ['ultrabomb']);

$superman_1->module->activate();
$superman_2->module->activate();

理解過程:

$container = new Container;
$container->bind('superman', function($container, $moduleName) {
         return new Superman($container->make($moduleName));
});
/*對上面程式碼的理解
$this->binds[superman] = function($container, $moduleName) {
         return new Superman($container->make($moduleName));
};
*/
$container->bind('xpower', function($container) {
         return new XPower;
});
/*對上面程式碼的理解
$this->binds['xpower'] = function($container) {
         return new XPower;
};
*/
$superman_1 = $container->make('superman', ['xpower']);
/*對上面程式碼的理解
$abstract= 'superman';
$parameters= ['xpower'];

array_unshift($parameters, $this);
$parameters =[$container,'xpower'];

call_user_func_array($this->binds[$abstract], $parameters);
call_user_func_array($this->binds[$superman], $parameters);
call_user_func_array( $this->binds['superman']=function($container, $moduleName) {
         return new Superman($container->make($moduleName));
} ,[$container,'xpower']);
$this->binds['superman'] = function($container, 'xpower') {
         return new Superman($container->make('xpower'));
};
$this->binds['superman'] = function($container, 'xpower') {
         return new Superman(call_user_func_array($this->binds('xpower'), [ ]));
};
$this->binds['superman'] = function($container, 'xpower') {
         return new Superman(function([]) {
                return new XPower;
         });
};
$superman_1 =new Superman($this->module=new XPower;);
*/
$superman_1->module->activate();
/*
echo "X-超能量";
*/

相關文章