首頁 >後端開發 >php教程 >php中Ioc和Di實例詳解

php中Ioc和Di實例詳解

墨辰丷
墨辰丷原創
2018-05-22 16:11:231784瀏覽

最近在使用ThinkPHP5框架,看了下他的原始碼,發現有很多地方也用到了依賴注入(控制反轉),覺得有必要和大家簡單聊一聊什麼是依賴注入以及怎麼使用它。

先看一個例子:

<?php

class A
{
	public $b;
	public $c;
	public function A()
	{
		//TODO
	}
	public function Method()
	{
		$this->b=new B();
		$this->c=new C();
		
		$this->b->Method();
		$this->c->Method();
		
		//TODO
	} 
}

class B
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}

class C
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}

$a=new A();
$a->Method();

?>

#上面程式碼,我們很容易理解一句話:

A類別依賴B類別與C類別

也就是說,如果今後開發過程中,要對B類別或C類別修改,一旦涉及函數改名,函數參數數量變動,甚至整個類別結構的調整,我們也要對A類做出相應的調整,A類的獨立性喪失了,這在開發過程中是很不方便的,也就是我們說的“牽一發動全身”,如果兩個類是兩個人分別寫的,矛盾往往就在這個時候產生了。 。 。

萬一真的要改動B類和C類,有沒有辦法,可以不去改動或盡量少改動A類的程式碼呢?這裡要用到控制反轉。

高層模組不應該依賴底層模組,兩個都應該依賴抽象。

控制反轉(IOC)是一種思想,依賴注入(DI)是實施這種思想的方法。

第一種方法叫做:建構器注入(這種方法也不建議用,但比不用好)

#
class A
{
	public $b;
	public $c;
	public function A($b,$c)
	{
		$this->b=$b;
		$this->c=$c;
	}
	public function Method()
	{
		$this->b->Method();
		$this->c->Method();
	} 
}

##客戶端類別這樣寫: 

$a=new A(new B(),new C());
$a->Method();

A類別的建構器依賴B類別和C類,透過建構器的參數傳入,至少實現了一點,就是B類別物件b和C類別物件c的建立都移至了A類別外,所以一旦B類別和C類別發生改動,A類別無需做修改,只要在client類別裡改就可以了

假如有一天,我們需要擴充B類,做兩個B類的子類

class B
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}
class B1 extends B
{
	public function B1()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b1&#39;;
	}
}
class B2 extends B
{
	public function B2()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b2&#39;;
	}
}

也很簡單,客戶端類別這麼寫:

$a=new A(new B2(),new C());
$a->Method();

所以A類別是不用關心B類別到底有哪些個子類別的,只要在客戶端類別關心就可以了。

第二種方法叫做:工廠模式註入(建議使用)

class Factory
{
	public function Factory()
	{
		//TODO
	}
	public function create($s)
	{
		switch($s)
		{
			case &#39;B&#39;:
			{
				return new B();
				break;
			}
			case &#39;C&#39;:
			{
				return new C();
				break;
			}
			default:
			{
				return null;
				break;
			}
		}
	}
}

我們A類別程式碼改為:

class A
{
	public $b;
	public $c;
	public function A()
	{
		//TODO
	}
	public function Method()
	{
		$f=new Factory();
		$this->b=$f->create(&#39;B&#39;);
		$this->c=$f->create(&#39;C&#39;);
		
		$this->b->Method();
		$this->c->Method();
		
		//TODO
	} 
}

其實已經解耦了一小部分,至少如果B類和C類的構造函數要是發生變化,比如修改函數參數等,我們只需要改Factory類就可以了。

抽像不應該依賴細節,細節應該依賴抽象。

把B類別和C類別中的方法再抽像出來,做一個介面

interface IMethod
{
	public function Method();
}

這樣,A類別中的$b變量而$c變數就不再是一個具體的變數了,而是一個抽象型別的變量,不到運行那一刻,不知道他們的Method方式是怎麼實現的。

class B implements IMethod
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}

class C implements IMethod
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}

總結幾點:

#1.我們把A類別中的B類物件和C類別物件的建立移至A類外

2.原本A類依賴B類和C類,現在變成了A依賴Factory,Factory依賴B和C。

相關推薦:

PHP控制反轉(IOC)和依賴注入(DI)的實例程式碼詳解

分享PHP依賴注入(DI)和控制反轉(IoC)的實例教學

#PHP 依賴注入(DI) 和控制反轉(IoC )實例教學

#

以上是php中Ioc和Di實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn