對於“控制反轉(IOC)”和“依賴注入(DI)”兩個概念,首先要明白以下概念:
- 控制反轉(IOC)是一種思想,依賴注入(DI)是實施這種思想的方法;
- IOC 意味著將你設計好的物件交給容器控制,而不是傳統的在物件內部控制;
- 依賴注入(DI)實現了控制反轉(IOC);
一:介面注入
<?php
/**
* 定義一個訊息介面
* Interface Message
*/
interface Message
{
public function send();
}
/**
* 傳送郵件的訊息類
* Class SendEmail
*/
class SendEmail implements Message
{
public function send()
{
echo "email 傳送成功!";
}
}
/**
* 傳送簡訊的訊息類
* Class SendSms
*/
class SendSms implements Message
{
public function send()
{
echo "sms 傳送成功!";
}
}
/**
* 模擬購買流程
* Class Order
*/
class Order
{
//TODO::下單
//TODO::購買
//傳送訊息
/**
* @var String 訊息內容
*/
protected String $message;
function __construct(Message $message)
{
$this->message = $message;
}
public function send_msg()
{
return $this->message->send();
}
}
//TODO::比如購買成功了,這裡開始傳送訊息
$message = new SendEmail();//傳送郵件
//$message = new SendEmail();//傳送簡訊
$order = new Order($message);
$order->send_msg();
分析
Order 類依賴訊息類的 Message 介面
$order = new Order($message);
具體的訊息類例項化交給外部處理,不論你是傳送簡訊還是郵件,你自己例項化就好,不要影響我的 Order 類,你只需要把 Message 的介面實現類給我就好
$message = new SendEmail();//傳送郵件
//$message = new SendEmail();//傳送簡訊
$order = new Order($message);
$order->send_msg();
二:構造器注入
<?php
/**
* 構造器注入
* 定義一個有建構函式的類
* Class IocB
*/
class iocAA
{
public $b;
public $c;
public function __construct($iocB, $iocC)
{
$this->b = $iocB;
$this->c = $iocC;
}
public function Method()
{
$this->b->Method();
$this->c->Method();
}
}
class IocB
{
public function Method()
{
echo '我是 IocB 的 Method 方法';
}
}
class IocC
{
public function Method()
{
echo '我是 IocC 的 Method 方法';
}
}
$a = new iocAA(new IocB(), new IocC());
$a->Method();
分析
進行例項化類的時候,對建構函式的兩個引數進行例項化賦值(將例項化後的物件賦值給 iocAA 類 的兩個屬性)
$a = new iocAA(new IocB(), new IocC());
然後呼叫物件的方法即可
$a->Method();
三:setter 方法注入
<?php
class IocC
{
private $db;
private $file;
function setDb($db)
{
$this->db = $db;
}
function setFile($file)
{
$this->file = $file;
}
}
class file
{
public function __construct()
{
echo "file 的 建構函式執行了" . "\n";
}
public function run()
{
echo "file 的 run" . "\n";
}
}
class db
{
public function __construct()
{
echo "db 的 建構函式執行了" . "\n";
}
public function run()
{
echo "db 的 run" . "\n";
}
}
$iocC = new IocC();
$iocC->setdb(new db());
$iocC->setfile(new file());
分析
先例項化 IocC 類
$iocC = new IocC();
接著呼叫 IocC 類的方法使用,呼叫 IocC 的方法 setDb 和 setFile 的時候,需要把例項化的物件當做引數傳進去
$iocC->setdb(new db());
$iocC->setfile(new file());
本作品採用《CC 協議》,轉載必須註明作者和本文連結