摘要:什么是觀察者模式觀察者模式用于實(shí)現(xiàn)對(duì)對(duì)象進(jìn)行觀察一旦主體對(duì)象狀態(tài)發(fā)生改變,與之關(guān)聯(lián)的觀察者對(duì)象會(huì)收到通知,并進(jìn)行相應(yīng)操作。應(yīng)用觀察者模式的好處觀察者模式解除了主體和具體觀察者的耦合,讓耦合的雙方都依賴于抽象,而不是依賴具體。
什么是觀察者模式
觀察者模式用于實(shí)現(xiàn)對(duì)對(duì)象進(jìn)行觀察:一旦主體對(duì)象狀態(tài)發(fā)生改變,與之關(guān)聯(lián)的觀察者對(duì)象會(huì)收到通知,并進(jìn)行相應(yīng)操作。
舉個(gè)例子說明:
假設(shè)一個(gè)這樣的情景,當(dāng)公司有一個(gè)新員工入職了,入職的當(dāng)天,HR需要為他辦理入職手續(xù),網(wǎng)管需要給他配好電腦和辦公用品,部門主管需要帶他熟悉部門。傳統(tǒng)的編程方式,就是在員工入職這個(gè)事件發(fā)生的代碼之后直接加入處理邏輯,當(dāng)后續(xù)我們需要增加處理邏輯時(shí)(比如員工入職后增加培訓(xùn)),代碼會(huì)變得難以維護(hù)。這種方式是耦合的,侵入式的,增加新的邏輯需要改變事件主題的代碼。運(yùn)用觀察者模式,將員工的入職作為事件,其他的處理邏輯都做為觀察者的操作,那么,當(dāng)以后需要再增加更多的邏輯時(shí),新增邏輯代碼就會(huì)很方便。具體代碼實(shí)現(xiàn)如下。
首先定義一個(gè)觀察者接口,所有的觀察者都實(shí)現(xiàn)這個(gè)接口(為什么要定義成接口呢?因?yàn)槊恳粋€(gè)觀察者的具體行為需要具體去實(shí)現(xiàn),用接口定義一個(gè)統(tǒng)一的方法,具體的實(shí)現(xiàn)交給觀察者去實(shí)現(xiàn))
interface observer { public function update(); }
再定義一個(gè)事件生成器的抽象類,用來使繼承它的事件都具有通知觀察者的能力。
abstract class EventGenerator { private $observers = []; //定義一個(gè)添加觀察者的方法 public function addOberver(Observer $observer) { $this->observers[] = $observer; } //定義一個(gè)通知觀察者的方法 public function notify() { foreach($this->observers as $observer) { $observer->update(); } } }
然后再來定義事件類
class event extends EventGenerator { //定義一個(gè)觸發(fā)觀察者的方法 public funtion trigger() { echo "Event
"; //開始通知觀察者 $this->notify(); } }
開始使用
$event = new event(); $event->trigger();
這個(gè)時(shí)候,當(dāng)我們要在事件發(fā)生的時(shí)候增加別的操作,只需要新增觀察者就可以了
新增一個(gè)觀察者
class Observer1 implements Observer { public function update() { echo "操作1
"; } }
然后使用的時(shí)候就是
$event = new event(); // 增加觀察者 $event->addObserver(new Observer1); $event->trigger();
如果需要在事件發(fā)生后再增加操作,只需再新增相應(yīng)的觀察者即可。
應(yīng)用觀察者模式的好處觀察者模式解除了主體和具體觀察者的耦合,讓耦合的雙方都依賴于抽象,而不是依賴具體。從而使得各自的變化都不會(huì)影響另一邊的變化。降低對(duì)象之間的耦合度以達(dá)到解耦的目的,符合"開閉原則"的要求。
利用 SPL 實(shí)現(xiàn)觀察者模式PHP 通過內(nèi)置的 SPL 擴(kuò)展提供了對(duì)觀察者模式的原生支持,其中的觀察者由 3 個(gè)元素組成 : SplObserver 接口、 SplSubject 接口和 SplObjectStorage 工具類。下面是利用 SPL 實(shí)現(xiàn)觀察者模式的代碼。SPL 的地址見這里。
class MyObserver1 implements SplObserver { public function update(SplSubject $subject) { echo __CLASS__ . " - " . $subject->getName(); } } class MyObserver2 implements SplObserver { public function update(SplSubject $subject) { echo __CLASS__ . " - " . $subject->getName(); } } class MySubject implements SplSubject { private $observers; private $name; public function __construct($name) { $this->observers = new SplObjectStorage(); $this->name = $name; } 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); } } public function getName() { return $this->name; } } $observer1 = new MyObserver1(); $observer2 = new MyObserver2(); $subject = new MySubject("test"); $subject->attach($observer1); $subject->attach($observer2); $subject->notify(); /* 輸出: MyObserver1 - test MyObserver2 - test */ $subject->detach($observer2); $subject->notify(); /* 輸出: MyObserver1 - test */
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26164.html
摘要:時(shí)間年月日星期二說明本文部分內(nèi)容均來自慕課網(wǎng)。慕課網(wǎng)教學(xué)源碼學(xué)習(xí)源碼第一章觀察者模式概述課程簡(jiǎn)介觀察者模式的定義定義對(duì)象間的一種一對(duì)多的依賴關(guān)系。 時(shí)間:2017年08月29日星期二說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:https://github.com/zccodere/s...學(xué)習(xí)源碼:https://github.com/z...
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
摘要:想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊?,否則只會(huì)讓你自己更痛苦。創(chuàng)建型設(shè)計(jì)模式主要有簡(jiǎn)單工廠模式,工廠方法模式,抽象工廠模式,建造者模式,原型模式和單例模式,下面一一道來。而工廠方法模式本意是將實(shí)際創(chuàng)建對(duì)象的工作推遲到子類中。 接觸前端兩三個(gè)月的時(shí)候,那時(shí)候只是聽說設(shè)計(jì)模式很重要,然后我就去讀了一本設(shè)計(jì)模式的書,讀了一部分,也不知道這些設(shè)計(jì)模式到底設(shè)計(jì)出來干嘛的,然后就沒再看了。后...
摘要:我們可以把取消發(fā)貨單和取消訂單看成一個(gè)被觀察或被訂閱的類實(shí)例的對(duì)象,一旦發(fā)生取消行為,我們立即通知各個(gè)觀察者做出相對(duì)應(yīng)的行為。裝飾器模式裝飾器思想,不管以前業(yè)務(wù)邏輯,甚至不去讀,調(diào)用之前的接口裝飾上新的數(shù)據(jù),達(dá)到自己的目的。 前言 還是每月的目標(biāo)至少寫一篇文章,一晃八月份就要過去了,這個(gè)月依然沒有什么產(chǎn)出,毫無疑問最近的狀態(tài)就是不停的工作,不停的加班。所以還是把最近工作進(jìn)行一個(gè)總結(jié),首...
閱讀 2129·2023-04-26 00:09
閱讀 3162·2021-09-26 10:12
閱讀 3525·2019-08-30 15:44
閱讀 2887·2019-08-30 13:47
閱讀 949·2019-08-23 17:56
閱讀 3259·2019-08-23 15:31
閱讀 501·2019-08-23 13:47
閱讀 2560·2019-08-23 11:56