標籤:logger 面向 物件導向 cas bsp ext monitor ble ons
觀察者模式按我的的理解,主要分為觀察者類和被被觀察者類二個部分。被觀察者類會繼承一個介面(如:Observable)實現對觀察者的添加、刪除和通知(即通知觀察者發生了特定事件),它彙總了觀察者類具體看原書類圖。而觀察者類繼承一個介面(如:Observer)實現一個抽象方法update(),以下程式碼範例中此方法還將接收一個參數即被觀察者,根據被觀察者的狀態來決定是否執行自身的商務邏輯。好了閑話不多說直接上代碼。
//被觀察者類
interface Observable {
function attach(Observer $observer); //添加觀察者
function detach(Observer $observer); //刪除觀察者
function notify(); //通知觀察者
}
//一個處理登陸資訊的類
class Login implements Observable{
const LOGIN_USER_UNKNOWN =1;
const LOGIN_WRONG_PASS =2;
const LOGIN_ACCESS =3;
private $status = array(); //觀察者的狀態
private $observers; //儲存觀察者對象
function __construct (){
$this->observers = array();
}
function attach(Observer $observer){
$this->observers[] = $observer;
}
function detach(Observer $observer){
$newobservers = array();
foreach(|$this->observers as $obs){
if($obs !== $observer){
$newobservers[]=$obs;
}
}
$this->observers = $newobservers;
}
function notify(){
foreach($this->observers as $obs){
$obs->update($this);
}
}
function handleLogin($user,$pass,$ip){
switch(rand(1,3)){ //這裡類比了3種登陸狀態
case 1:
$this->setStatus(self::LOGIN_ACCESS,$user,$ip); //設定被觀察者的狀態,通知觀察者後,觀察者將跟據狀態來執行相應的商務邏輯
$ret =true;
break;
case 2:
$this->setStatus(self::LOGIN_WRONG_PASS,$user,$ip);
$ret =false;
break;
case 3:
$this->setStatus(self::LOGIN_USER_UNKNOWN,$user,$ip);
$ret =false;
break;
}
$this->notify():
return $ret;
//...............
}
private function setStatus($status,$user,$ip){
$this->status = array($status,$user,$ip)
}
}
//觀察者類
interface Observer{
function update(Observable $observable);
}
//這個類主要是為了確保傳遞過來的被觀察者對象是login類,因為只有login才有setStatus方法,上面的Observer為了保證它的通用性所以沒有加入抽象方法setStatus
abstract class LoginObserver implements Observer{
private $login;
function __construct (Login $login){
$this->login=$login;
$login->attach($this);
}
function update(Observable $observable){
if($observable === $this->login){
$this->doUpdate($observable);
}
}
abstract function doUpdate(Login $login);
}
class SecurityMonitor extends LoginObserver{ //登陸時密碼錯誤的話就發郵件給管理者
function doUpdate(Login $login){
$status = $login->getStatus();
if($status[0] == Login::LOGIN_WRONG_PASS){
//發送郵件
}
}
}
class GeneralLogger extends LoginObserver{ //..........
function doUpdate(Login $login){
$status = $login->getStatus();
//記錄登陸資料
}
}
class partnershipTool extends LoginObserver{ //.........
function doUpdate(Login $login){
$status = $login->getStatus();
//檢查iP,設定Cookie
}
}
最後: 路漫漫其修遠兮,吾將上下而求索!
PHP物件導向之觀察者模式