觀察者模式
在PHP SPL中已經(jīng)提供SplSubject和SqlOberver接口,源碼如下:
// 主題 被觀察者
interface SplSubject {
public function attach(SplObserver $observer); //注冊(cè)觀察者到當(dāng)前主題
public function detach(SplObserver $observer); //從當(dāng)前主題刪除觀察者
public function notify(); //主題狀態(tài)更新時(shí)通知所有的觀察者做相應(yīng)的處理
}
// 觀察者
interface SplObserver {
public function update(SplSubject $subject); //注冊(cè)觀察者到當(dāng)前主題
}
-------------------------------------具體實(shí)現(xiàn)-------------------------------------
<?php
/**
* 主題類(lèi)(被觀察者相當(dāng)于一個(gè)主題,觀察者訂閱這個(gè)主題)
* 當(dāng)我們注冊(cè)用戶(hù)成功的時(shí)候想發(fā)送 email 和 sms 通知用戶(hù)注冊(cè)成功
* 則 可以將 SendEmail 和 SendSms 作為觀察者
* 注冊(cè)到 User 的觀察者中
* 當(dāng) User register 成功時(shí) notify 給 observers
* 各 observe 通過(guò)約定的 update 接口進(jìn)行相應(yīng)的處理 發(fā)郵件或發(fā)短信
*/
class User implements SplSubject
{
public $name;
public $email;
public $mobile;
/**
* 當(dāng)前主題下的觀察者集合
* @var array
*/
private $observers = [];
/**
* 模擬注冊(cè)
* @param [type] $name [description]
* @param [type] $email [description]
* @param [type] $mobile [description]
* @return [type] [description]
*/
public function register($name, $email, $mobile)
{
$this->name = $name;
$this->email = $email;
$this->mobile = $mobile;
//business handle and register success
$reg_result = true;
if ($reg_result) {
$this->notify(); // 注冊(cè)成功 所有的觀察者將會(huì)收到此主題的通知
return true;
}
return false;
}
/**
* 當(dāng)前主題注冊(cè)新的觀察者
* @param SplObserver $observer [description]
* @return [type] [description]
*/
public function attach(SplObserver $observer)
{
return array_push($this->observers, $observer);
}
/**
* 當(dāng)前主題刪除已注冊(cè)的觀察者
* @param SplObserver $observer [description]
* @return [type] [description]
*/
public function detach(SplObserver $observer)
{
$key = array_search($observer, $this->observers, true);
if (false !== $key) {
unset($this->observers[$key]);
return true;
}
return false;
}
/**
* 狀態(tài)更新 通知所有的觀察者
* @return [type] [description]
*/
public function notify()
{
if (! empty($this->observers)) {
foreach ($this->observers as $key => $observer) {
$observer->update($this);
}
}
return true;
}
}
-------------------------------------Email/Sms 觀察者-------------------------------------
/**
* 觀察者通過(guò) update 來(lái)接受主題的更新通知
*/
class EmailObserver implements SplObserver
{
/**
* 觀察者接收主題通知的接口
* @param SplSubject $user [description]
* @return [type] [description]
*/
public function update(SplSubject $user)
{
echo "send email to " . $user->email . PHP_EOL;
}
}
class SmsObserver implements SplObserver
{
public function update(SplSubject $user)
{
echo "send sms to " . $user->mobile . PHP_EOL;
}
}
-------------------------------------業(yè)務(wù)-------------------------------------
// User 主題
$user = new User();
// 為 user 注冊(cè) Email 觀察者 (Email 觀察者訂閱 User 主題)
$emailObserver = new EmailObserver();
$user->attach($emailObserver);
// 為 user 注冊(cè) Sms 觀察者 (Sms 觀察者訂閱 User 主題)
$smsObserver = new SmsObserver();
$user->attach($smsObserver);
// 從 user 上刪除 Sms 觀察者 (Sms 觀察者取消訂閱 User 主題)
//$user->detach($smsObserver);
// register 中會(huì)根據(jù)注冊(cè)結(jié)果通知觀察者 觀察者做相應(yīng)的處理
$user->register("big cat", "32448732@qq.com", "1888888888");
-------------------------------------結(jié)果-------------------------------------
send email to 1226432372@qq.com
send sms to 1888888888
[Finished in 0.1s]
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。