如果你曾經了解過依賴注入,那么你可能見過 “控制反轉”(Inversion of Control) 或者 “依賴反轉準則”(Dependency Inversion Principle)這種說法。這些是依賴注入能解決的更復雜的問題。
### 控制反轉
顧名思義,一個系統通過組織控制和對象的完全分離來實現”控制反轉”。對于依賴注入,這就意味著通過在系統的其他地方控制和實例化依賴對象,從而實現了解耦。
一些 PHP 框架很早以前就已經實現控制反轉了,但是問題是,應該反轉哪部分以及到什么程度?比如, MVC 框架通常會提供超類或者基本的控制器類以便其他控制器可以通過繼承來獲得相應的依賴。這就是控制反轉的例子,但是這種方法是直接移除了依賴而不是減輕了依賴。
依賴注入允許我們通過按需注入的方式更加優雅地解決這個問題,完全不需要任何耦合。
### 依賴反轉準則
依賴反轉準則是面向對象設計準則 S.O.L.I.D 中的 “D” ,倡導 “依賴于抽象而不是具體”。簡單來說就是依賴應該是接口/約定或者抽象類,而不是具體的實現。我們能很容易重構前面的例子,使之遵循這個準則
~~~
<?php
namespace Database;
class Database
{
protected $adapter;
public function __construct(AdapterInterface $adapter)
{
$this->adapter = $adapter;
}
}
interface AdapterInterface {}
class MysqlAdapter implements AdapterInterface {}
~~~
現在 Database 類依賴于接口,相比依賴于具體實現有更多的優勢。
假設你工作的團隊中,一位同事負責設計適配器。在第一個例子中,我們需要等待適配器設計完之后才能單元測試。現在由于依賴是一個接口/約定,我們能輕松地模擬接口測試,因為我們知道同事會基于約定實現那個適配器
這種方法的一個更大的好處是代碼擴展性變得更高。如果一年之后我們決定要遷移到一種不同的數據庫,我們只需要寫一個實現相應接口的適配器并且注入進去,由于適配器遵循接口的約定,我們不需要額外的重構。
- 歡迎
- 入門指南
- 使用當前穩定版本
- 內置的WEB服務器
- Mac安裝
- Windows安裝
- 代碼風格指南
- 語言亮點
- 編程范式
- 命名空間
- PHP標準庫
- 命令行接口
- Xdebug
- 依賴管理
- Composer 與 Packagist
- PEAR
- 開發實踐
- 基礎知識
- 日期和時間
- 設計模式
- 使用UTF8編碼
- 依賴注入
- 基本概念
- 復雜的問題
- 容器
- 延伸閱讀
- 數據庫
- MYSQL 擴展
- PDO 擴展
- 數據庫交互
- 數據庫抽象層
- 使用模板
- 好處
- 原生PHP模板
- 編譯模板
- 延伸閱讀
- 錯誤與異常
- 錯誤
- 異常
- 安全
- Web應用程序安全
- 密碼哈希
- 數據過濾
- 配置文件
- 注冊全局變量
- 錯誤報告
- 測試
- 測試驅動開發
- 行為驅動開發
- 其他測試工具
- 服務器與部署
- Platform as a Service (PaaS)
- 虛擬或專用服務器
- 共享服務器
- 構建及部署應用
- 虛擬化
- Vagrant
- Docker
- 緩存
- Opcode緩存
- 對象緩存
- 文檔撰寫
- 資源
- 社區
- Credits