依賴注入模式中,爲什麼用對象而不是用數組傳遞?

依賴注入(Dependence Injection, DI) 依賴注入是控制反轉的一種設計模式。依賴注入的核心是把類所依賴的單元的實例化過程,放到類的外面去實現。依賴注入的實現離不開反射。

依賴注入(Dependence Injection, DI)

所謂的依賴注入,指將依賴的對象通過參數的形式一次性傳入,使用時不需要顯式 new 了,比如把A類所依賴的B類、C類等以屬性或者構造函數等方式注入A類而不是直接在A類中實例化。

只要不是由內部生產(比如初始化、構造函數中通過工廠方法、自行手動 new 的),而是由外部以參數或其他形式注入的,都屬於依賴注入(DI) 。

依賴注入需要利用反射實現,比如:

class A
{
    protected $b;

    public function __constrcut(B $b)
    {
        $this->b = $b;
    }
}

// 通過控制反轉容器生成 A 的實例時,會通過反射發現 A 的構造函數需要一個 B 類的實例
// 於是自動向 A 類的構造函數注入 B 類的實例
$a = IoC::make(A::class);

依賴注入的實質就是把一個類不可更換的部分可更換的部分 分離開來,通過注入的方式來使用,從而達到解耦的目的。
比如有一個 Mysql 數據庫連接類如下:

class Mysql {
    private $host;
    private $port;
    private $username;
    private $password;
    private $db_name;
    public function construct(){
        $this->host = '127.0.0.1';
        $this->port = 22;
        $this->username = 'root';
        $this->password = '';
        $this->db_name = 'db';
    }
    public function connect()
    {
        return mysqli_connect($this->host,$this->username ,$this->password,$this->db_name,$this->port);
    }
}

// 使用
$db = new Mysql();
$con = $db->connect();

可更換部分是數據庫的配置

class Configuration
{
    private $host;
    private $port;
    private $username;
    private $password;
    private $db_name;
    public function construct(string $host, int $port, string $username, string $password,string $db_name)
    {
        $this->host = $host;
        $this->port = $port;
        $this->username = $username;
        $this->password = $password;
        $this->db_name = $db_name;
    }
    public function getHost(): string
    {
        return $this->host;
    }
    public function getPort(): int
    {
        return $this->port;
    }
    public function getUsername(): string
    {
        return $this->username;
    }
    public function getPassword(): string
    {
        return $this->password;
    }
    public function getDbName(): string
    {
        return $this->db_name;
    }
}

不可更換部分是Mysql數據庫的連接操作

class Mysql
{
    private $configuration;
    public function construct(DatabaseConfiguration $config)
    {
        $this->configuration = $config;
    }
    public function connect(){
        return mysqli_connect($this->configuration->getHost(),$this->configuration->getUsername() ,
        $this->configuration->getPassword,$this->configuration->getDbName(),$this->configuration->getPort());
    }
}

這樣就完成了配置文件和連接邏輯的分離,使用如下:

$config = new Configuration('127.0.0.1', 'root', '', 'my_db', 22);
$db = new Mysql($config);
$con = $db->connect();

$config是注入Mysql的,這就是所謂的依賴注入。

總結

注入可以理解成從外面把東西打進去。因此,依賴注入模式中,要分清內和外,要解除依賴的類內部就是內,實例化所依賴單元的地方就是外。在外通過構造形參,爲類內部的抽象單元提供實例化,達到解耦的目的,使下層依賴於上層,而不是上層依賴於下層。

因此,依賴注入模式中,要用對象傳遞,通過一個實例的反射來實現,這是數組做不到的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章