[转]Cocos2d-x观察者模式
Cocos2d-x設(shè)計(jì)模式發(fā)掘——觀察者模式
1、應(yīng)用場(chǎng)景
在cocos2d-x中的CCNotificationCenter類,它除了應(yīng)用單例模式以外,還應(yīng)用了觀察者模式。CCNotificationCenter類是觀察者模式中的目標(biāo)對(duì)象,而CCNotificationObserver則是觀察者。
一個(gè)目標(biāo)對(duì)象可以注冊(cè)多個(gè)觀察者,當(dāng)目標(biāo)對(duì)象的狀態(tài)改變的時(shí)候,可以通知觀察者對(duì)象作出相應(yīng)的響應(yīng)。這是標(biāo)準(zhǔn)的觀察者模式的實(shí)現(xiàn),但是CCNotificationCenter稍微有些許差別。
首先,CCNotificationCenter不是通過自身狀態(tài)改變來通知觀察者,而是通過顯式地發(fā)送觀察者感興趣的消息(postNotification)來通知它們。每一種消息類型可以對(duì)應(yīng)多個(gè)觀察者,同時(shí),每一個(gè)觀察者也可以“觀察”多個(gè)消息類型。其次,觀察者定義相應(yīng)的響應(yīng)事件同消息類型關(guān)聯(lián),當(dāng)某個(gè)地方觸發(fā)postNotification來廣播一個(gè)消息的時(shí)候,CCNotificationCenter會(huì)遍歷所有的觀察者,判斷它們注冊(cè)的消息類型是否匹配,如果匹配,則觸發(fā)相應(yīng)的注冊(cè)響應(yīng)事件。最后,該觀察者模式采用的是推模型,即由目標(biāo)對(duì)象去通知所有的觀察者。
其實(shí)CCNotificationCenter和CCNotificationObserver更準(zhǔn)確的叫法是:訂閱發(fā)布模式。
?
2、使用此模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1)實(shí)現(xiàn)了目標(biāo)對(duì)象和觀察者之間的抽象耦合,在本例中,則是實(shí)現(xiàn)了消息與觀察者的抽象耦合。可以定義一種消息與消息處理對(duì)象的一對(duì)多的關(guān)系,而不用擔(dān)心彼此的實(shí)現(xiàn)細(xì)節(jié)。
2)觀察者模式可以定義某種意義上的廣播通信機(jī)制。
3)實(shí)現(xiàn)訂閱者與發(fā)布者的松散耦合,同時(shí)保障了良好的擴(kuò)展性。
缺點(diǎn):
1)注冊(cè)成為CCNotificationCenter的觀察者后,如果忘記調(diào)用removeObserver,則會(huì)引起內(nèi)存泄漏。因?yàn)閍ddObserver會(huì)把觀察者的引用計(jì)算加1。
?
3、此模式的定義及一般實(shí)現(xiàn)
定義:
定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。
UML圖:
?
一般實(shí)現(xiàn):
可以參考CCNotificationCenter.h和CCNotification.cpp文件的實(shí)現(xiàn)。
?
4、游戲開發(fā)中如何運(yùn)用此模式
我們考慮cocos2d-x中一個(gè)非常典型的應(yīng)用場(chǎng)景,你的GameScene里面有兩個(gè)layer,一個(gè)gameLayer,它包含了游戲中的對(duì)象,比如玩家、敵人等。另一個(gè)層是HudLayer,它包含了游戲中顯示分?jǐn)?shù)、生命值等信息。如何讓這兩個(gè)層相互通信。
1)第一種辦法,你可以讓gameLayer包含一個(gè)hudLayer的引用,同時(shí)也可以讓hudLayer包含一個(gè)gameLayer的引用。注意!這里問題出現(xiàn)了,如果兩個(gè)類都包含彼此的強(qiáng)引用(所謂強(qiáng)引用就是retain),就會(huì)引起循環(huán)引用的情況,如果其中一個(gè)類包含的是弱引用,問題就不會(huì)出現(xiàn)。循環(huán)引用是使用引用計(jì)數(shù)管理內(nèi)存的一個(gè)致命弱點(diǎn),會(huì)導(dǎo)致資源永遠(yuǎn)得不到釋放,而且查錯(cuò)起來非常麻煩。
2)第二種辦法,把gameScene做成一個(gè)單例,同時(shí)讓gameScene包含gameLayer和hudLayer的弱引用,這樣就可以直接通過[GameScene sharedInstance].gameLayer或者[GameScene sharedInstance].hudLayer來訪問了。
3)第三種辦法,使用gameLayer->getParent()獲得gameScene,再使用gameScene來獲得hudLayer。
4)第四種辦法,使用CCNotificationCenter。當(dāng)hudLayer注冊(cè)它感興趣的消息,當(dāng)gameLayer需要通知hudLayer的時(shí)候,只需通過CCNotificationCenter發(fā)送一個(gè)對(duì)應(yīng)的消息即可。
?
5、此模式與其它模式的關(guān)系
觀察者模式是實(shí)現(xiàn)MVC模式的重要組成部分,一個(gè)model可以對(duì)應(yīng)多個(gè)views,model就是目標(biāo)對(duì)象,而view則是觀察者,當(dāng)model改變的時(shí)候,要通知所有的view也相應(yīng)的改變。
轉(zhuǎn)載于:https://www.cnblogs.com/Clin/archive/2013/05/06/3063076.html
總結(jié)
以上是生活随笔為你收集整理的[转]Cocos2d-x观察者模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 邀嫦娥
- 下一篇: 菱形继承,多继承,虚继承、虚表的内存结构