1. 程式人生 > 其它 >依賴注入和控制反轉

依賴注入和控制反轉

控制反轉(IOC)

Ioc意味著將你設計好的物件交給容器控制,而不是傳統的在你的物件內部直接控制

  • 如何理解?
    要明確“誰控制誰,控制什麼,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了”
    通常我們是在程式(消費者)裡邊直接new一個新物件(被依賴物件),建立一個依賴的物件。

1.誰來控制誰:Ioc有一個專門的容器,來建立這些物件(外部資源),而不是由(消費者顯示使用new)。
2.控制什麼?那就是主要控制了外部資源獲取和生命週期(不只是物件也包括檔案等)
3.為何是反轉?
3.1 傳統應用程式是由我們自己在物件中主動控制去直接獲取依賴物件,也就是正轉;
3.2 而反轉則是由容器來幫忙建立及注入依賴物件;
4.為何是反轉?因為由容器幫我們查詢及注入依賴物件,物件只是被動的接受依賴物件,所以是反轉;
5.哪些方面反轉了?依賴物件的獲取

被反轉了。

依賴注入(DI)

是元件之間依賴關係由容器在執行期決定,形象的說,即由容器動態的將某個依賴關係注入到元件之中.
依賴是為了提高元件重用頻率,且擴充套件更加方便靈活。

  • 如何理解
    理解DI的關鍵是:“誰依賴誰,為什麼需要依賴,誰注入誰,注入了什麼”
    1.誰依賴於誰:當然是應用程式依賴於IOC容器;
    2.為什麼需要依賴:應用程式需要IOC容器來提供物件需要的外部資源;
    3.誰注入誰:很明顯是IOC容器注入應用程式某個物件,應用程式依賴的物件;
    4.注入了什麼:就是注入某個物件所需要的外部資源(包括物件、資源、常量資料)。

  • 常用實現方法

    1. 建構函式注入
    2. setMethod()注入
    3. 通過介面定義注入方法,程式實現該方法
  • Ioc demo

/**
 * 控制反轉類
 */
class Ioc {
    /**
     * @var array 註冊的依賴陣列
     */
    protected static $registry = array();

    /**
     * 新增一個 resolve (匿名函式)到 registry 陣列中
     *
     * @param string  $name    依賴標識
     * @param Closure $resolve 一個匿名函式,用來建立例項
     * @return void
     */
    public static function register($name, Closure $resolve) {
        static::$registry[$name] = $resolve;
    }

    /**
     * 返回一個例項
     *
     * @param string $name 依賴的標識
     * @return mixed
     * @throws \Exception
     */
    public static function resolve($name) {
        if (static::registered($name)) {
            $name = static::$registry[$name];
            return $name();
        }

        throw new \Exception("Nothing registered with that name");
    }

    /**
     * 查詢某個依賴例項是否存在
     *
     * @param string $name
     * @return bool
     */
    public static function registered($name) {
        return array_key_exists($name, static::$registry);
    }
}

/**
-- Usage:

Ioc::register("book", function () {
    $book = new Book();
    $book->setdb('db');
    $book->setfile('file');

    return $book;
});

// 注入依賴
$book = Ioc::resolve('book');

 */

參考
對IOC和DI的通俗理解
PHP 依賴注入(DI) 和 控制反轉(IoC)
"深入理解DIP、IoC、DI以及IoC容器"