《Cocos2d-x设计模式》由会员分享,可在线阅读,更多相关《Cocos2d-x设计模式(52页珍藏版)》请在金锄头文库上搜索。
1、Cocos2dx 设计模式设计模式在程序设计中会经常用到,也许你从来没有留意过设计模式,其实你却一直在使用设计模式!Cocos2d-x 中有不少的设计模式,本系列教程主要讨论 Cocos2d-x 中的设计模式,看看引擎都使用了哪些设计模式,我们今后写代码要怎样使用某种设计模式。如果有任何错误还请留言指教,互相探讨。设计模式之观察者模式详解什么是观察者一个目标对象可以注册多个观察者,当目标对象的状态改变的时候,可以通知观察者对象作出相应的响应。这是标准的观察者模式的实现。 观察者模式又称为发布-订阅模式。优缺点优点:- 实现了目标对象和观察者之间的抽象耦合,在本例中,则是实现了消息与观察者的抽象
2、耦合。可以定义一种消息与消息处理对象的一对多的关系,而不用担心彼此的实现细节。缺点:- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。适用场合一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A 对象的行为将影响 B 对象, B 对象的行为将影响 C 对象,可以使用观察者模式创建一种链式触发机制。JAV
3、A 实现采用发布-订阅模式,例如报社(被观察者)有很多订阅者(观察者) ,每天的早晨有新报纸就通知所有的订阅者。Office.java:报社12345678910111213public interface Office /添加观察者public void addObserver(People p);/删除观察者public void deleteObserver(People p);/通知所有的观察者public void notifyObservers(String msg);People.java:人public interface People /收到来自观察者的消息public vo
4、id update(String msg);BrightOffice.java:光明日报12345678910111213141516171819public class BrightOffice /所有观察者的集合private ArrayList peopleList = new ArrayList();public void addObserver(People p) this.peopleList.add(p);public void deleteObserver(Observer o) this.peopleList.remove(o);public void notifyObser
5、vers(String msg) for (People p : peopleList) p.update(msg);/通知public void publish() this.notifyObservers(今天出新报纸啦!);OldPeople.java:老人123456public class OldPeople implements Peoplepublic void update(String msg) System.out.println(msg);System.out.println(我要去取今天的新报纸啦!);Test.java:测试程序12345678public class
6、 Test public static void main(String args) People p1 = new OldPeople();BrightOffice brightOffice = new BrightOffice();brightOffice.addObserver(p1);brightOffice.publish(); Cocos2d-x 中的观察者在 Cocos2d-x 中被观察者是 NotificationCenter,但它不是通过自身状态改变来通知观察者,而是通过显示地发送观察者感兴趣的消息(postNotification)来通知它们。每一种消息类型可以对应多个观察
7、者,同时,每一个观察者也可以“观察”多个消息类型。其次,观察者定义相应的响应事件同消息类型关联,当某个地方触发 postNotification 来广播一个消息的时候,NotificationCenter 会遍历所有的观察者,判断它们注册的消息类型是否匹配,如果匹配,则触发相应的注册响应事件。最后,该观察者模式采用的是推模型,即由目标对象去通知所有的观察者。 其实 NotificationCenter 和 NotificationObserver 更准确的叫法是:订阅发布模式。观后感CCNotificationObserver 相当于一个组装器,把 object(对象)、func(对象的方法)
8、 、name( 事件)组装到一起,变成一个 Observer 实体。 CCNotificationCenter 中封装了一个 CCArray 容器,同一个对象、不同事件可以当做不同的 Observer 添加,总之,是以 event 来区别不同的观察者而不是 object。实例1234567/添加观察者CCNotificationCenter:sharedNotificationCenter()-addObserver(this, callfuncO_selector(HelloWorld:myNotification), MY_NOTIFICATION, NULL); /* 一般的在接受通知的
9、一方在接受完通知后需要 remove 监听。(注意第二个方法: returns the number of observers removed)*/void removeObserver(CCObject *target,const char *name); int removeAllObservers(CCObject *target); /事件名字89101112131415161718192021222324252627282930313233343536373839404142434445464748495051CCNotificationCenter:sharedNotificati
10、onCenter()-postNotification(MNOTIFICATION, (CCObject*)1);CCNotificationCenter.h/* js NA:不适用* lua NA:不适用*/观察者class CC_DLL CCNotificationObserver : public CCObjectpublic:/* brief 构造一个观察者* param target 想做观察者的对象* param selector 回调方法* param name 消息名字* param obj 将被传递给回调函数的额外参数*/CCNotificationObserver(CCOb
11、ject *target, SEL_CallFuncO selector,const char *name,CCObject *obj);/* 释放成员 */CCNotificationObserver(); /* target 通过回调方法调用 obj */void performSelector(CCObject *obj);private:/* 定义 CCObject 类型的对象 m_target,并创建一个 getTarget 方法 */CC_PROPERTY_READONLY(CCObject *, m_target, Target);CC_PROPERTY_READONLY(SEL
12、_CallFuncO, m_selector, Selector);CC_PROPERTY_READONLY(char *, m_name, Name);CC_PROPERTY_READONLY(CCObject *, m_object, Object);/创建 get 和 set 方法CC_PROPERTY(int, m_nHandler,Handler);/被观察者class CC_DLL CCNotificationCenter : public CCObjectprivate:/判断是否存在 name 名字的 targetbool observerExisted(CCObject *t
13、arget,const char *name);/观察者集合CCArray *m_observers;/lua 专用int m_scriptHandler;public:525354555657585960616263646566676869707172737475767778798081828384858687/* 构造函数,初始化集合 m_observers */CCNotificationCenter();/* 释放集合 m_observers */CCNotificationCenter();/* 获取单例对象 */static CCNotificationCenter *shared
14、NotificationCenter(void);/* 销毁单例对象 */static void purgeNotificationCenter(void);/* 添加观察者* param target 观察者* param selector 观察者的回调方法* param name 通知消息* param 传给回调方法的额外参数*/void addObserver(CCObject *target, SEL_CallFuncO selector,const char *name,CCObject *obj);/* brief 移除指定 name 的 target* param target
15、The target of this notification.* param name The name of this notification. */void removeObserver(CCObject *target,const char *name);/* brief 移除这个 target 的所有观察者* param target.* returns 返回被移除观察者的数量 */int removeAllObservers(CCObject *target);/* lua 脚本中使用的注册、注销观察者*/void registerScriptObserver(CCObject
16、*target,int handler,const char* name);void unregisterScriptObserver(CCObject *target,const char* name);/* 执行指定 name 的观察者的回调方法 */void postNotification(const char *name);void postNotification(const char *name, CCObject *object);/* 获取脚本的回调方法 */inline int getScriptHandler() return m_scriptHandler; ;int getObserverHandlerByName(const char* name);二段构建模式乍一看