python ioc di_PHP的依赖注入(DI) 和 控制反转(IoC)
要想理解 PHP 依賴注入 和 控制反轉 兩個概念,就必須搞清楚如下的兩個問題:DI —— Dependency Injection 依賴注入
IoC —— Inversion of Control 控制反轉
什么是依賴注入:
沒有你我就活不下去,那么,你就是我的依賴。 說白了就是:不是我自身的,卻是我需要的,都是我所依賴的。一切需要外部提供的,都是需要進行依賴注入的。
依賴注入舉例:class?Boy {
protected?$girl;
public?function?__construct(Girl?$girl) {
$this->girl =?$girl;
}
}
class?Girl {
...
}
$boy?=?new?Boy();??// Error; Boy must have girlfriend!
// 所以,必須要給他一個女朋友才行
$girl?=?new?Girl();
$boy?=?new?Boy($girl);?// Right! So Happy!
從上述代碼我們可以看到Boy強依賴Girl必須在構造時注入Girl的實例才行。
那么為什么要有依賴注入這個概念,依賴注入到底解決了什么問題?
我們將上述代碼修正一下我們初學時都寫過的代碼:class?Boy {
protected?$girl;
public?function?__construct() {
$this->girl =?new?Girl();
}
}
這種方式與前面的方式有什么不同呢?
我們會發現Boy的女朋友被我們硬編碼到Boy的身體里去了。。。 每次Boy重生自己想換個類型的女朋友都要把自己扒光才行。
某天Boy特別喜歡一個LoliGirl ,非常想讓她做自己的女朋友。。。怎么辦? 重生自己。。。扒開自己。。。把Girl扔了。。。把 LoliGirl塞進去?????class?LoliGirl {
}
class?Boy {
protected?$girl;
public?function?__construct() {
//? $this->girl = new Girl();? // sorry...
$this->girl =?new?LoliGirl();
}
}
某天 Boy迷戀上了御姐....Boy 好煩。。。
是不是感覺不太好?每次遇到真心相待的人卻要這么的折磨自己。。。
Boy說,我要變的強大一點。我不想被改來改去的!
好吧,我們讓Boy強大一點:interface?Girl {
// Boy need knows that I have some abilities.
}
class?LoliGril implement Girl {
// I will implement Girl"s abilities.
}
class?Vixen implement Girl {
// Vixen definitely is a girl, do not doubt it.
}
class?Boy {
protected?$girl;
public?function?__construct(Girl?$girl) {
$this->girl =?$girl;
}
}
$loliGirl?=?new?LoliGirl();
$vixen?=?new?Vixen();
$boy?=?new?Boy($loliGirl);
$boy?=?new?Boy($vixen);
Boy 很高興,終于可以不用扒開自己就可以體驗不同的人生了。。。So Happy!
依賴注入方式
1、構造器 注入<?php
class?Book {
private?$db_conn;
public?function?__construct($db_conn) {
$this->db_conn =?$db_conn;
}
}
2、setter 注入<?php
class?Book {
private?$db;
private?$file;
function?setdb($db) {
$this->db =?$db;
}
function?setfile($file) {
$this->file =?$file;
}
}
class?file {
}
class?db {
}
// ...
class?test {
$book?=?new?Book();
$book->setdb(new?db());
$book->setfile(new?file());
}
小結:
因為大多數應用程序都是由兩個或者更多的類通過彼此合作來實現業務邏輯,這使得每個對象都需要獲取與其合作的對象(也就是它所依賴的對象)的引用。如果這個獲取過程要靠自身實現,那么將導致代碼高度耦合并且難以維護和調試。
控制反轉 (Inversion Of Control, IOC)
控制反轉 是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做 依賴注入(Dependency Injection, DI), 還有一種叫"依賴查找"(Dependency Lookup)。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。<?php
class?Ioc {
protected?$db_conn;
public?static?function?make_book() {
$new_book?=?new?Book();
$new_book->set_db(self::$db_conn);
//...
//...
//其他的依賴注入
return?$new_book;
}
}
此時,如果獲取一個book實例,只需要執行$newone = Ioc::makebook();
以上是container的一個具體實例,最好還是不要把具體的某個依賴注入寫成方法,采用registry注冊,get獲取比較好<?php
/**
* 控制反轉類
*/
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);
}
}
現在就可以通過如下方式來注冊和注入一個<?php
Ioc::register("book",?function?() {
$book?=?new?Book();
$book->setdb("db");
$book->setfile("file");
return?$book;
});
// 注入依賴
$book?= Ioc::resolve("book");
問題匯總
1、參與者都有誰?
答:一般有三方參與者,一個是某個對象;一個是IoC/DI的容器;另一個是某個對象的外部資源。又要名詞解釋一下,某個對象指的就是任意的、普通的Java對象; IoC/DI的容器簡單點說就是指用來實現IoC/DI功能的一個框架程序;對象的外部資源指的就是對象需要的,但是是從對象外部獲取的,都統稱資源,比如:對象需要的其它對象、或者是對象需要的文件資源等等。
2、依賴:誰依賴于誰?為什么會有依賴?
答:某個對象依賴于IoC/DI的容器。依賴是不可避免的,在一個項目中,各個類之間有各種各樣的關系,不可能全部完全獨立,這就形成了依賴。傳統的開發是使用其他類時直接調用,這會形成強耦合,這是要避免的。依賴注入借用容器轉移了被依賴對象實現解耦。
3、注入:誰注入于誰?到底注入什么?
答:通過容器向對象注入其所需要的外部資源
4、控制反轉:誰控制誰?控制什么?為什么叫反轉?
答:IoC/DI的容器控制對象,主要是控制對象實例的創建。反轉是相對于正向而言的,那么什么算是正向的呢?考慮一下常規情況下的應用程序,如果要在A里面使用C,你會怎么做呢?當然是直接去創建C的對象,也就是說,是在A類中主動去獲取所需要的外部資源C,這種情況被稱為正向的。那么什么是反向呢?就是A類不再主動去獲取C,而是被動等待,等待IoC/DI的容器獲取一個C的實例,然后反向的注入到A類中。
5、依賴注入和控制反轉是同一概念嗎?
答:從上面可以看出:依賴注入是從應用程序的角度在描述,可以把依賴注入描述完整點:應用程序依賴容器創建并注入它所需要的外部資源;而控制反轉是從容器的角度在描述,描述完整點:容器控制應用程序,由容器反向的向應用程序注入應用程序所需要的外部資源。
參考:
Laravel 中的 依賴注入 與 控制反轉
總結
以上是生活随笔為你收集整理的python ioc di_PHP的依赖注入(DI) 和 控制反转(IoC)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: u8 和 char如何转化_如何编写高效
- 下一篇: python中使用grpc方法示例_在P