观察者模式的重要作用就是解耦,将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至毫无依赖。UI系统需要一套机制来使UI层和具体的业务逻辑解耦,观察者模式这个时候就可以派上用场。观察者模式就是一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
使用场景:关联行为场景,关联行为是可拆分的,而不是组合关系;事件多级触发场景;跨系统的消息交换场景,如消息队列,事件总线等。
实例UML:
通用UML:
观察者模式多了一个在同步方法调用上的额外跳转以及动态分配消耗,虽然有这些缺点,但在代码性能瓶颈以外的地方都可以很好的应用。观察者模式是同步的,当有耗时的操作要执行时,将这些操作推到另一个线程或工作队列中,还有就是当观察者试图获取被观察者拥有的锁时,游戏就进入了死锁。
可以使用链表来替代数组存储观察者列表,这样内存利用率高,但是在删除某个观察者时需要O(N),通过使用双向链表可以使删除操作变为O(1)。
使用观察者对象作为链表节点,这暗示它只能存在与一个观察者链表中,但实现中,每个观察者对象有独立的列表,一个观察者同时可以存在于多个列表,因此我们可以采用链表节点池。通过预先在对象池中分配固定大小的列表节点,可以随你使用和重用,无需牵扯到真正的内存分配器。
销毁观察者时,需要其对应的被观察者的观察者列表中移除其。销毁被观察者时,需要移除其观察者中的被观察者列表,此时需要双向指针。如果是垃圾回收机制,需要注意失效监听者的现象。
订阅功能就是观察者模式的现实运用,当有新的信息时,所有的订阅用户都将自动获取新的信息。