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

黄舟
發布: 2023-03-06 15:40:01
原創
1906 人瀏覽過

先看一個範例:


<?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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板