觀察者模式

/**

  • 優(yōu)才網(wǎng)公開課示例代碼
  • 觀察者模式 Observer
  • @author 優(yōu)才網(wǎng)全棧工程師教研組
  • @seehttp://www.ucai.cn
    */
    function output($string) {
    echo $string . "\n";
    }
    //訂單數(shù)據(jù)對象簡單模擬,這個是實際需要被觀察的對象(Subject),但是我們將其獨立伺绽,然后
    //通過構(gòu)造方法傳入到我們模式中的Subject中,這樣使具體業(yè)務更加獨立
    class Order{
    //訂單號
    private $id = '';
    //用戶ID
    private $userId = '';
    //用戶名
    private $userName = '';
    //價格
    private $price = '';
    //下單時間
    private $orderTime = '';
    //訂單數(shù)據(jù)填充簡單模擬鉴吹,實際應用中可能會讀取用戶表單輸入并處理
    public function __set($name, $value){
    if(isset($this->$name)){
    $this->$name = $value;
    }
    }
    //獲取訂單屬性
    public function __get($name){
    if(isset($this->$name)) {
    return $this->$name;
    }
    return "";
    }
    }
    //被觀察者, 負責維護觀察者并在變化發(fā)生是通知觀察者
    class OrderSubject implements SplSubject {
    private $observers;
    private $order;
    public function __construct(Order $order) {
    $this->observers = new SplObjectStorage();
    $this->order = $order;
    }
    //增加一個觀察者
    public function attach(SplObserver $observer) {
    $this->observers->attach($observer);
    }
    //移除一個觀察者
    public function detach(SplObserver $observer) {
    $this->observers->detach($observer);
    }
    //通知所有觀察者
    public function notify() {
    foreach ($this->observers as $observer) {
    $observer->update($this);
    }
    }
    //返回主體對象的具體實現(xiàn)东揣,供觀察者調(diào)用
    public function getOrder() {
    return $this->order;
    }
    }
    //記錄業(yè)務數(shù)據(jù)日志 (ActionLogObserver),實際可能還要抽象一層以處理不同的Action(業(yè)務操作)铲敛,這里省略
    class ActionLogObserver implements SplObserver{
    public function update(SplSubject $subject) {
    $order = $subject->getOrder();
    //實際應用可能會寫到日志文件中待错,這里直接輸出
    output( "[OrderId:{$order->id}] [UseId:{$order->userId}][Price:{$order->price}]" );
    }
    }
    //給用戶發(fā)送訂單確認郵件 (UserMailObserver)
    class UserMailObserver implements SplObserver{
    public function update(SplSubject $subject) {
    $order = $subject->getOrder();
    //實際應用會調(diào)用郵件發(fā)送服務如sendmail籽孙,這里直接輸出
    output( "Dear {$order->userName}: Your order {$order->id} wasconfirmed!" );
    }
    }
    //給管理人員發(fā)訂單處理通知郵件 (AdminMailObserver)
    class AdminMailObserver implements SplObserver{
    public function update(SplSubject $subject) {
    $order = $subject->getOrder();
    //實際應用會調(diào)用郵件發(fā)送服務如sendmail,這里直接輸出
    output( "Dear Manager: User{$order->userName}(ID:{$order->userId}) submitted a new order{$order->id}, please handle it ASAP!" );
    }
    }
    //假設(shè)的DB類火俄,便于測試犯建,實際會存入真實數(shù)據(jù)庫
    class FakeDB{
    public function save($data){
    return true;
    }
    }
    class Client {
    public static function test() {
    //初始化一個訂單數(shù)據(jù)
    $order= new Order();
    $order->id = 1001;
    $order->userId = 9527;
    $order->userName = "God";
    $order->price = 20.0;
    $order->orderTime = time();
    //綁定觀察者
    $subject = new OrderSubject($order);
    $actionLogObserver = new ActionLogObserver();
    $userMailObserver = newUserMailObserver();
    $adminMailObserver = new AdminMailObserver();
    $subject->attach($actionLogObserver);
    $subject->attach($userMailObserver);
    $subject->attach($adminMailObserver);
    //向數(shù)據(jù)庫保存訂單
    $db =new FakeDB();
    $result = $db->save($order);
    if($result){
    //通知觀察者
    $subject->notify();
    }
    }
    }
    Client::test();
    ?>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瓜客,隨后出現(xiàn)的幾起案子适瓦,更是在濱河造成了極大的恐慌,老刑警劉巖谱仪,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玻熙,死亡現(xiàn)場離奇詭異,居然都是意外死亡疯攒,警方通過查閱死者的電腦和手機嗦随,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敬尺,“玉大人枚尼,你說我怎么就攤上這事贴浙。” “怎么了署恍?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵崎溃,是天一觀的道長。 經(jīng)常有香客問我盯质,道長袁串,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任呼巷,我火速辦了婚禮囱修,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朵逝。我一直安慰自己,他們只是感情好乡范,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布配名。 她就那樣靜靜地躺著,像睡著了一般晋辆。 火紅的嫁衣襯著肌膚如雪渠脉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天瓶佳,我揣著相機與錄音芋膘,去河邊找鬼。 笑死霸饲,一個胖子當著我的面吹牛为朋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厚脉,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼习寸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了傻工?” 一聲冷哼從身側(cè)響起霞溪,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎中捆,沒想到半個月后鸯匹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡泄伪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年殴蓬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟋滴。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡科雳,死狀恐怖根蟹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情糟秘,我是刑警寧澤简逮,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站尿赚,受9級特大地震影響散庶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凌净,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一悲龟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冰寻,春花似錦须教、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至划乖,卻和暖如春贬养,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背琴庵。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工误算, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迷殿。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓儿礼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庆寺。 傳聞我的和親對象是個殘疾皇子蜘犁,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容