观察者的前世今生

观察者的前世今生

观察者是一个非常棒的消息通信机制模式,许多优秀的框架都使用了观察者模式的思想。

====================

观察者模式的前生

这里我想借着观察者,聊聊回调。因为这真的是一个有趣的东西。而它也正是观察者的前生。

我把回调理解为开发者的一个小进阶。为什么这么说呢?

回调解决了所有初级程序猿都会遇到棘手问题:

A → B   B → A  A调用B,B如何反过来调用A
新手通常都会使用静态变量来解决这个问题。

回调可以轻而易举的解决这个问题,但新手理解回调却是一个艰难的过程,因为这完全打破了固有的思维方式。其原因有二:

  • 接口可以理解为一种名实分离的概念。继承形象化的父子关系更容易被理解,接口就不那么容易了。因为它比较特殊,一个空空的东西……但其实将接口也认为是继承,理解起来就容易了一点。(所以回调你也可以用继承实现哦~)

  • Java的引用类似于简化版的指针,对新手也不是那么容易理解的东西。所以在回调中,就难去理解,我中有你,你中有我,你那里的我还是我这里的我吗?

难理解是真的,但真的理解了以后,在感叹的同时也会发现它还是很简单的。也对接口和JAVA的引用有了较深的理解。

观察者的优化建议

先说观察者的三种模式
  • 链式结构,一条触发链的结构。你通知我,我通知他。

  • 分发结构。通过观察者做消息或事件分发。

  • 单一回调(最简的回调也是一种观察者嘛)

优化
  • 观察者包装与分类

    传统的观察者模式,都是被观察者将观察者存于一个集合中,当需要发送消息时,通过遍历向每个观察者发消息。这是一种效率低下的行为,尤其观察者非常多的时候,可以通过一些方法将观察者分类,每次只遍历需要的一部分。

  • 异步分发。

    普通的消息分发都是按照顺序的,一旦中间有卡壳,那么后面的完蛋了。而且如果要求速度的话,建议异步分发。

  • 观察者的保存使用Set还是List

    如果有避免一个对象重复注册的需求,那么可以开始考虑使用Set,但到底用不用呢?

    Set可以更快的查重,List可以更快的遍历。

    如果注册需求大于消息分发需求,使用Set。消息分发需求大于注册需求,使用List。而往往后者的情况更多一些。

观察者的缺点

  • 死循环链与链堵塞。

    需要注意的是,被观察者也可以成为观察者,而一旦形成一链式结构,一是很容易造成死循环,二是链过长导致维护困难,调试困难。

    而在链过长的情况下,同步顺序分发中一旦中间某个节点分发错误,就造成后面的消息堵塞发不出去。链断开。

  • 观察者的取消问题。

    观察者模式最大的缺点,观察者的取消注册问题!!

    Java的引用机制与GC机制很容易导致OOM。在观察者进被观察者中时,弱被观察者不被销毁,观察者的引用将被一直抓着不能被释放。而这种情况在被观察者设为单例的情况下更加严峻。

    所以什么时候取消注册是一件非常棘手的事情。我们都希望可以观察在最后一刻,可什么时候是最后一刻却很难确定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值