Cocos中的观察者设计模式与通知机制
观察者模式概述
观察者(Observer)模式,也被称为发布/订阅(Publish/Subscribe)模式,是 MVC(模型 - 视图 - 控制器)模式的重要组成部分。
为了更好地理解观察者模式,我们来看一个生活中的例子。天气一直是英国人热衷讨论的话题,近年来,天气变化也备受中国人关注。比如,我会依据天气预报决定是乘坐地铁还是开车上班,我的女儿则会根据天气预报选择明天要穿的衣服。为此,我在移动公司为手机定制了天气预报短信通知服务,其工作模型如下:每天,气象局将天气预报信息投送给移动运营商,移动运营商的短信中心负责把天气预报发送给定制了这项服务的手机。
在软件系统中,一个对象状态的改变往往会连带影响其他多个对象的状态。虽然实现这一需求的设计方案有很多,但观察者模式因其具备强复用性和对象间匿名通信的特点,成为了最为合适的选择之一。
实现原理
观察者模式包含 4 个核心角色,具体如下:
- 抽象主题(Subject):抽象主题是一个接口,它充当观察者集合的容器。该接口定义了三个重要函数:添加观察者的
add函数、移除观察者的remove函数以及为所有观察者发送通知的notifyObserver函数。 - 抽象观察者(Observer):抽象观察者同样是一个接口,它仅包含一个
update函数,用于在接收到通知时进行状态更新。 - 具体观察者(ConcreteObserver):具体观察者是
Observer接口的具体实现,负责实现update函数的具体逻辑。 - 具体主题(ConcreteSubject):具体主题是
Subject接口的具体实现,负责管理观察者集合,并在状态改变时调用notifyObserver函数通知所有观察者。
引入 Subject 和 Observer 这两个接口后,系统的可复用性得到显著提高,同时耦合度也大大降低。由于 ConcreteSubject 通常只需要一个实例,因此我们可以采用单例设计模式来实现。此外,观察者模式还有其他变形,若要深入了解,可以参考 GoF(《设计模式 - 可复用的面向对象软件元素》)。
通知机制
在 Cocos2d - x 框架中,观察者模式的一种具体应用是通知(notification)机制。通知机制与委托机制有所不同,前者实现的是“一对多”的对象间通信,而后者则是“一对一”的对象间通信。
在通知机制中,对某个通知感兴趣的所有对象都可以成为接收者。具体流程如下:首先,这些对象需要向通知中心(__NotificationCenter)调用 addObserver 函数进行注册。当投送对象将通知投送给通知中心时,通知中心会把该通知广播给所有注册过的接收者。所有接收者并不知道通知的投送者是谁,也无需关心通知的具体细节,投送对象与接收者之间呈现一对多的关系。如果接收者对通知不再关注,可以调用通知中心的 removeObserver 或 removeAllObservers 函数解除注册,之后便不再接收该通知。
在参数回传方面,通知机制相较于委托模式具有明显优势。通知机制可以实现一对多的参数传递,而委托模式只能进行一对一的参数传递。