本文主要是介绍观察者的前世今生,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
观察者的前世今生
观察者是一个非常棒的消息通信机制模式,许多优秀的框架都使用了观察者模式的思想。
====================
观察者模式的前生
这里我想借着观察者,聊聊回调。因为这真的是一个有趣的东西。而它也正是观察者的前生。
我把回调理解为开发者的一个小进阶。为什么这么说呢?
回调解决了所有初级程序猿都会遇到棘手问题:
A → B B → A A调用B,B如何反过来调用A
新手通常都会使用静态变量来解决这个问题。
回调可以轻而易举的解决这个问题,但新手理解回调却是一个艰难的过程,因为这完全打破了固有的思维方式。其原因有二:
接口可以理解为一种名实分离的概念。继承形象化的父子关系更容易被理解,接口就不那么容易了。因为它比较特殊,一个空空的东西……但其实将接口也认为是继承,理解起来就容易了一点。(所以回调你也可以用继承实现哦~)
Java的引用类似于简化版的指针,对新手也不是那么容易理解的东西。所以在回调中,就难去理解,我中有你,你中有我,你那里的我还是我这里的我吗?
难理解是真的,但真的理解了以后,在感叹的同时也会发现它还是很简单的。也对接口和JAVA的引用有了较深的理解。
观察者的优化建议
先说观察者的三种模式
链式结构,一条触发链的结构。你通知我,我通知他。
分发结构。通过观察者做消息或事件分发。
单一回调(最简的回调也是一种观察者嘛)
优化
观察者包装与分类
传统的观察者模式,都是被观察者将观察者存于一个集合中,当需要发送消息时,通过遍历向每个观察者发消息。这是一种效率低下的行为,尤其观察者非常多的时候,可以通过一些方法将观察者分类,每次只遍历需要的一部分。
异步分发。
普通的消息分发都是按照顺序的,一旦中间有卡壳,那么后面的完蛋了。而且如果要求速度的话,建议异步分发。
观察者的保存使用Set还是List
如果有避免一个对象重复注册的需求,那么可以开始考虑使用Set,但到底用不用呢?
Set可以更快的查重,List可以更快的遍历。
如果注册需求大于消息分发需求,使用Set。消息分发需求大于注册需求,使用List。而往往后者的情况更多一些。
观察者的缺点
死循环链与链堵塞。
需要注意的是,被观察者也可以成为观察者,而一旦形成一链式结构,一是很容易造成死循环,二是链过长导致维护困难,调试困难。
而在链过长的情况下,同步顺序分发中一旦中间某个节点分发错误,就造成后面的消息堵塞发不出去。链断开。
观察者的取消问题。
观察者模式最大的缺点,观察者的取消注册问题!!
Java的引用机制与GC机制很容易导致OOM。在观察者进被观察者中时,弱被观察者不被销毁,观察者的引用将被一直抓着不能被释放。而这种情况在被观察者设为单例的情况下更加严峻。
所以什么时候取消注册是一件非常棘手的事情。我们都希望可以观察在最后一刻,可什么时候是最后一刻却很难确定。
这篇关于观察者的前世今生的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!