首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

從「超人與超能力」理解 IoC 容器與依賴注入(DI)核心原理

     編輯:PHP 相關知識

從「超人與超能力」理解 IoC 容器與依賴注入(DI)核心原理

本文通過「超人需要超能力」的生動隱喻,層層遞進講解面向對象設計中依賴產生、工廠模式、依賴注入(DI)至 IoC 容器的演進邏輯,並關聯 Laravel 服務容器實現。

依賴的產生與痛苦

class Superman {
    protected $power;
    public function __construct() {
        $this->power = new Power(999, 100); // 硬編碼依賴
    }
}

超人與具體超能力強耦合,新增/變更能力需修改 Superman 類,違反開閉原則。

工廠模式:依賴轉移

class SuperModuleFactory {
    public function makeModule($name, $options) {
        switch ($name) {
            case 'Flight': return new Flight($options[0], $options[1]);
            case 'Force': return new Force($options[0]);
            case 'Shot': return new Shot($options[0], $options[1], $options[2]);
        }
    }
}

class Superman {
    public function __construct(array $modules) {
        $factory = new SuperModuleFactory;
        foreach ($modules as $name => $opts) {
            $this->power[] = $factory->makeModule($name, $opts);
        }
    }
}

依賴從「多個具體類」轉移到「單一工廠」,但工廠類本身成為新的耦合點,擴展需修改工廠代碼。

依賴注入(DI):控制反轉(IoC)

定義接口契約,外部注入實現:

interface SuperModuleInterface {
    public function activate(array $target);
}

class XPower implements SuperModuleInterface { /* ... */ }
class UltraBomb implements SuperModuleInterface { /* ... */ }

class Superman {
    protected $module;
    public function __construct(SuperModuleInterface $module) {
        $this->module = $module; // 構造器注入
    }
}

// 使用
$superman = new Superman(new XPower);

DI 核心:依賴不由類內部創建,而是由外部通過構造器、Setter 或接口注入。實現了「高層模塊不依賴低層模塊,雙方依賴抽象」。

IoC 容器:自動化的超級工廠

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($c, $moduleName) {
    return new Superman($c->make($moduleName));
});
$container->bind('xpower', fn($c) => new XPower);
$container->bind('ultrabomb', fn($c) => new UltraBomb);

// 自動解析依賴並生產
$superman_1 = $container->make('superman', ['xpower']);
$superman_2 = $container->make('superman', ['ultrabomb']);
// Superman Object ( [module:protected] => XPower Object ( ) )

容器通過 bind 註冊解析邏輯,make 時遞歸解析依賴。真正的 IoC 容器(如 Laravel)利用 反射(Reflection) 自動分析構造器參數類型提示,實現零配置自動注入。

Laravel 服務容器核心組件

  • Service Provider:分離註冊(register)與啟動(boot),確保依賴就緒。
  • Facade:提供靜態調用語法糖,底層將 Route::get() 映射到容器解析的 Illuminate\Routing\Router 實例。

理解 IoC/DI 不僅是掌握框架用法,更是掌握可維護、可測試、可擴展的面向對象設計精髓。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved