觀察者模式(Observer),當一個對象的狀態發生改變時,依賴他的對象會全部收到通知,並自動更新。
場景: 一個事件發生後,要執行一連串更新操作.傳統的編程方式,就是在事件的代碼之後直接加入處理邏輯,當更新得邏輯增多之後,代碼會變得難以維護.這種方式是耦合的,侵入式的,增加新的邏輯需要改變事件主題的代碼,而觀察者模式實現了低耦合,非侵入式的通知與更新機制
觀察者模式典型實現方式:
1、定義2個接口:觀察者(通知)接口、被觀察者(主題)接口
2、定義2個類,觀察者對象實現觀察者接口、主題類實現被觀者接口
3、主題類註冊自己需要通知的觀察者
4、主題類某個業務邏輯發生時通知觀察者對象,每個觀察者執行自己的業務邏輯。
示例:如以下代碼
<?php
#===================定義觀察者、被觀察者接口============
/**
*
* 觀察者接口(通知接口)
*
*/
interface LoginObserver //觀察者接口
{
function loginDo($args); //得到通知後調用的方法
}
/**
*
* 主題接口
*
*/
interface LoginObservable //被觀察對象接口
{
function addObserver($observer); //提供註冊觀察者方法
}
#====================主題類實現========================
/**
*
* 主題類(登錄)
* 實現主題接口(被觀察者)
*/
class Login implements LoginObservable {
//通知數組(觀察者)
private $_observers = [];
//處理登錄流程
public function sureLogin($user)
{
//循環通知,調用其loginDo實現不同業務邏輯
foreach ( $this->_observers as $obs ) {
//$this 可用來獲取主題類句柄,在通知中使用
$obs->loginDo($user);
}
}
//添加通知
public function addObserver($observer) //添加N個通知
{
$this->_observers [] = $observer;
}
}
#=========================定義多個通知====================
//記錄日誌
class LoginLogs implements LoginObserver {
public function loginDo($user) {
echo " 用戶".$user['name']."登錄成功<br>";
}
}
//添加積分
class LoginIntegral implements LoginObserver {
public function loginDo($user) {
echo " 贈送".$user['name']."1積分。<br>";
}
}
#============================用戶登錄====================
$login = new Login ();
$login->addObserver (new LoginLogs ()); //根據不同業務邏輯加入各種通知
$login->addObserver (new LoginIntegral ());
//登錄
$user = [
'id' => 1,
'name' => '張三',
];
$login->sureLogin($user);