定义对象之间的一对多依赖,这样当一个对象改变状态时,他的所有依赖者都会收到通知并完成更新。
有一天,老板兴高采烈的对我说:“当某个召唤师在打野的时候被野怪杀死,是不是该羞辱他一下?” 没错,当这种情况发生,应该第一时间通知他的队友,要认真play!
对于这种一对多的关系,当然会想到观察者模式。很多高级编程语言库中都会提供相应的API,例如iOS中的NSNotificationCenter类。但是,接下来讨论的是如何自己去实现更加灵活的观察者模式。
一般将观察者模式分为“主题”与“订阅者”两部分。主题可以增加、删除订阅者,并且当特定的事件发生后,会通知所有的订阅者;而订阅者则是收到通知后更新自己的一些行为。
首先要定义Subject和Observer接口(协议),然后定义一个具体主题类BlueBuff,用于实现Subject接口(协议),定义三个订阅者类Summoner1、Summoner2、Summoner3,用于实现Observer接口(协议),如下图:
每当主题有变化,就会通知订阅者,这样的设计其实不够灵活、高效。就拿BlueBuff跟Summoner来说,对于BlueBuff的每次攻击,Summoner并不想都收到通知,而是某次攻击KO了对方,才希望得到通知。因此在Subject中添加了isChanged变量,用来控制某个特定的时间点才发送通知给订阅者们。
另外,对于所有的订阅者,他们感兴趣的数据可能并不相同,那么主题将全部的数据通知给订阅者,显然有些多余。其实可以设计成让订阅者主动去到主题中拉取感兴趣的数据,这样需要在主题类中留出拉取部分通知数据的方法,例如下面对图1的更改:
接下来简单描述一下iOS中的观察者模式NSNotificationCenter类:
在使用NSNotificationCenter类时,aName字符串最好能清晰的描述出observer对象与SEL结构来,比如在ViewController类中这样使用addObserver:selector:name:object方法:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(ljaction:)
name:@"AppDelegate+ViewController+ljaction"
object:nil];
aName被定义为AppDelegate+ViewController+ljaction,意思就是ViewController、AppDelegate类中的ljaction方法。这样在得到观察者模式带来的松耦合的同时,也不至于失去逻辑追踪的线索。
倾情告白:使用观察者模式达到了松耦合的设计目的,能够建立更有弹性的OO系统。
关注微信公众号CodingArtist,可以第一时间得到文章更新通知! _