iOS 設(shè)計(jì)模式的應(yīng)用 ⑩ 觀察者模式

前言

????在現(xiàn)實(shí)生活中,如果我們想知道某個(gè)領(lǐng)域的最新消息俺陋,我們可能會(huì)訂閱很多相關(guān)的信息源豁延,比如報(bào)紙、微博腊状、公眾號(hào)诱咏、廣播、電視等等缴挖。任何人都可以在任何時(shí)候查閱而不會(huì)打擾其他人袋狞。我們把這一思想引入面向?qū)ο筌浖O(shè)計(jì)中來(lái),用以消除具有不同行為的對(duì)象之間的耦合映屋。通過(guò)這一模式苟鸯,不同對(duì)象可以協(xié)同工作,同時(shí)它們也可以被復(fù)用于其它地址棚点。我們稱(chēng)之為觀察者模式早处。

什么是觀察者模式

????觀察者模式也叫做發(fā)布-訂閱模式。如它的別名暗示一樣瘫析,它很像雜志的訂閱砌梆。當(dāng)從雜志發(fā)布商訂閱雜志時(shí),讀者把名字和郵寄地址提供給發(fā)行商颁股,這樣新的一期就能送到讀者手上么库。這正是觀察者模式的工作方式。觀察者模式定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系甘有,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí)诉儒,所有依賴(lài)于它的對(duì)象都得到通知并被自動(dòng)更新。

觀察者模式的類(lèi)圖.png

????ObserverSubject 訂閱通知亏掀。 ConcreteObserver 實(shí)現(xiàn)抽象并重載 update 方法忱反。一旦 Subject 的實(shí)例需要通知 Observer 任何新的變更泛释, Subject 會(huì)通過(guò) notify 方法發(fā)送 Update 消息來(lái)通知存儲(chǔ)在內(nèi)部列表中所有注冊(cè)的 Observer,在 ConcreteObserverupdate 方法的實(shí)現(xiàn)中温算, Subject 的內(nèi)部狀態(tài)可以被取得并在以后進(jìn)行處理怜校。

什么時(shí)候使用觀察者模式

  • 有兩種抽象類(lèi)型相互依賴(lài)。將它們封裝在各自的對(duì)象中注竿,就可以對(duì)它們單獨(dú)進(jìn)行改變和復(fù)用茄茁。
  • 對(duì)一個(gè)對(duì)象的改變需要同時(shí)改變其它對(duì)象,而不知道具體有多少對(duì)象有待改變巩割。
  • 一個(gè)對(duì)象必須通知其它對(duì)象裙顽,而它又不需要知道其它對(duì)象是什么。
  • 需要在系統(tǒng)中創(chuàng)建一個(gè)觸發(fā)鏈宣谈,A對(duì)象的行為將影響B(tài)對(duì)象愈犹,B對(duì)象的行為將影響C對(duì)象……,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制闻丑。

觀察者模式的優(yōu)缺點(diǎn)

觀察者模式的優(yōu)點(diǎn)

  1. 觀察者和被觀察者是抽象耦合的漩怎。
  2. 建立一套觸發(fā)機(jī)制。

觀察者模式的缺點(diǎn)

  1. 如果一個(gè)被觀察者對(duì)象有很多的直接和間接的觀察者的話嗦嗡,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間勋锤。
  2. 如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴(lài)的話,觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用酸钦,可能導(dǎo)致系統(tǒng)崩潰怪得。
  3. 觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道所觀察的目標(biāo)對(duì)象是怎么發(fā)生變化的,而僅僅只是知道觀察目標(biāo)發(fā)生了變化卑硫。

Cocoa 中的觀察者模式

NSNotification

???? Cocoa 的通知機(jī)制基于觀察者模式實(shí)現(xiàn)了消息的一對(duì)多廣播。程序中的對(duì)象將自己或其他對(duì)象添加到列表中一個(gè)或多個(gè)通知的觀察者蚕断,每個(gè)通知都由一個(gè)全局字符串(通知名稱(chēng))標(biāo)識(shí)欢伏。想要通知其他對(duì)象的對(duì)象——被觀察對(duì)象——?jiǎng)?chuàng)建一個(gè)通知對(duì)象并將其發(fā)布到通知中心。通知中心確定特定通知的觀察者亿乳,并通過(guò)消息將通知發(fā)送給他們硝拧。通知消息調(diào)用的方法必須符合某個(gè)單參數(shù)簽名。該方法的參數(shù)是通知對(duì)象葛假,其中包含通知名稱(chēng)障陶、觀察對(duì)象和包含任何補(bǔ)充信息的字典。

???? 發(fā)布通知是一個(gè)同步過(guò)程聊训。在通知中心向所有觀察者廣播通知之前抱究,發(fā)布對(duì)象不會(huì)重新獲得控制權(quán)。對(duì)于異步行為带斑,可以將通知放入通知隊(duì)列鼓寺;控制立即返回到發(fā)布對(duì)象勋拟,通知中心在到達(dá)隊(duì)列頂部時(shí)廣播通知。

???? 常規(guī)通知(即通知中心廣播的通知)僅在進(jìn)程內(nèi)妈候。如果要向其他進(jìn)程廣播通知敢靡,可以使用分布式通知中心及其相關(guān)API。

通知類(lèi)是 NSNotification(用于通知對(duì)象)苦银、NSNotificationCenter(發(fā)布通知和添加觀察者)啸胧、NSNotificationQueue(將通知入隊(duì))

Key-Value Observer

???? 鍵值觀察是一種機(jī)制,它允許對(duì)象在其他對(duì)象的特定屬性發(fā)生更改時(shí)得到通知幔虏。它基于 <NSKeyValueObserving> 非正式協(xié)議纺念。觀察到的屬性可以是簡(jiǎn)單的屬性、一對(duì)一關(guān)系或一對(duì)多關(guān)系所计。在模型-視圖-控制器模式的上下文中柠辞,鍵值觀察尤其重要,因?yàn)樗挂晥D對(duì)象能夠通過(guò)控制器層觀察模型對(duì)象的變化主胧。因此叭首,它是 Cocoa 的重要組成部分綁定技術(shù)。

????Cocoa 提供了許多方法的默認(rèn)“自動(dòng)”實(shí)現(xiàn) <NSKeyValueObserving> 協(xié)議踪栋,為所有符合要求的對(duì)象提供了屬性觀察能力焙格。

關(guān)于 Key-Value Observer 可以移步 了解 Key-Value Observing

通知與鍵-值 觀察之間的主要差別

通知 鍵-值觀察
一個(gè)中心對(duì)象為所有觀察者提供變更通知 被觀察的對(duì)象直接向觀察者發(fā)送通知
廣義上關(guān)注程序事件 綁定于特定對(duì)象屬性的值

總結(jié)

????當(dāng)對(duì)象間存在一對(duì)多關(guān)系時(shí),則使用觀察者模式(Observer Pattern)夷都。關(guān)于觀察者模式眷唉,Cocoa 框架為我們提供了兩種實(shí)現(xiàn)好的觀察者模式: NSNotificationKey-Value Observer

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末囤官,一起剝皮案震驚了整個(gè)濱河市冬阳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌党饮,老刑警劉巖肝陪,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異刑顺,居然都是意外死亡氯窍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)蹲堂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狼讨,“玉大人,你說(shuō)我怎么就攤上這事柒竞≌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鲫骗。 經(jīng)常有香客問(wèn)我犬耻,道長(zhǎng),這世上最難降的妖魔是什么执泰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任枕磁,我火速辦了婚禮,結(jié)果婚禮上术吝,老公的妹妹穿的比我還像新娘计济。我一直安慰自己,他們只是感情好排苍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布沦寂。 她就那樣靜靜地躺著,像睡著了一般淘衙。 火紅的嫁衣襯著肌膚如雪传藏。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天彤守,我揣著相機(jī)與錄音毯侦,去河邊找鬼。 笑死具垫,一個(gè)胖子當(dāng)著我的面吹牛侈离,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筝蚕,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼卦碾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了起宽?” 一聲冷哼從身側(cè)響起洲胖,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坯沪,沒(méi)想到半個(gè)月后宾濒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屏箍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了橘忱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赴魁。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钝诚,靈堂內(nèi)的尸體忽然破棺而出颖御,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布潘拱,位于F島的核電站疹鳄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芦岂。R本人自食惡果不足惜瘪弓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望禽最。 院中可真熱鬧腺怯,春花似錦、人聲如沸川无。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)懦趋。三九已至晾虑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仅叫,已是汗流浹背帜篇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惑芭,地道東北人坠狡。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像遂跟,于是被迫代替她去往敵國(guó)和親逃沿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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