依賴注入模式用來減少程序間的耦合。
當一個類要使用另一個類時,一般的寫法如下:
<?php
class Test1
{
public function say()
{
echo 'hello';
}
}
class Test2
{
public $test1;
public function communicate()
{
$this->test1 = new Test1();
$this->test1->say(); // 調用C類中的方法
//Do something else
}
}
$test2 = new Test2();
$test2->communicate();
當在Test2需要使用Test1時,Test2主動實例化了Test1類,很顯然Test2類依賴Test1類,如果以后要修改Test1類的類名,必然要對Test2類做相應的修改,這樣Test2類就和Test1類緊緊耦合在了一起。
如何降低這兩個類之間的耦合行呢?看如下經過改造后的代碼:
<?php
class Test1
{
public function say()
{
echo 'hello';
}
}
class Test2
{
public $test1;
public function __construct(Test1 $test1)
{
$this->test1 = $test1;//實例化c類
}
public function communicate()
{
$this->test1->say(); // 調用C類中的方法
//Do something else
}
}
$test1 = new Test1();
$test2 = new Test2($test1);
$test2->communicate();
Test2不再主動實例化Test1類,而是先創建一個Test1的對象,然后將Test1對象注入到Test2中,這種方法中如果Test1類發生改動,Test2類無需做相應的修改。這就是依賴注入模式的一種實現。依賴注入共有三種模式:構造方法注入,setter方法注入和接口注入。上面的例子就是構造方法注入。構造方法注入的弊端是Test2類依賴的類較多,實例化時參數列表會很長,容易發生混亂。
setter方法注入示例如下:
<?php
class Test1
{
public function say()
{
echo 'hello';
}
}
class Test2
{
public $test1;
public function setTest1(Test1 $test1)
{
$this->test1 = $test1;
}
public function communicate()
{
$this->test1->say(); // 調用C類中的方法
//Do something else
}
}
$test1 = new Test1();
$test2 = new Test2();
$test2->setTest1($test1)
$test2->communicate();
這種方式的弊端是當依賴的類增多時,需要很多的set方法。
另一種實現方法,同理只不過是吧construct改成了別的方法中實例化類了
<?php /** * 當有了IoC/DI的容器后,a類依賴c實例注入的示例 */ /** * Class c */ class c { public function say() { echo 'hello'; } } /** * Class a */ class a { private $c; public function setC(C $c) { $this->c = $c; // 實例化創建C類 } public function sayC() { echo $this->c->say(); // 調用C類中的方法 } } $c = new C(); $a = new a(); $a->setC($c); $a->sayC();
