您的位置:网站首页 > IT观察 > 正文

设计模式之观察者模式源码分析及实践

类别:IT观察 日期:2018-6-2 19:57:08 人气: 来源:

  4月27日,滴滴出行与国际金融公司(IFC)签署合作谅解备忘录,将在新兴市场中女性发展、数字普惠金融、绿色金融及跨国合作等领域的合作。滴滴表示,在这一合作框架下,双方将探索利用数字技术实现赋能女性乘客、司机、女性中小型企业主及女性员工。

  本篇来自Marker_Sky的,分享了观察者模式 源码分析和在 RecyclerView 中的体现,一起来看看!希望大家喜欢。

  最近在学习 EventBus 和 RxJava 相关知识,了解到两者都使用了观察者模式。以前对该模式只有一个模糊的概念,导致看 E 和 R 时一知半解,所以下定决心把这个模式仔细回顾和记录一下。

  观察者模式相关概念定义:一个对象和多个形成依赖关系,当一个对象改变状态,所以依赖于它的对象都会得到通知并执行相应逻辑。

  简单理解:A 是被观察者,B、C、D 是观察者。当 A 发生变化时发出通知告知 B、C、D,然后 B、C、D 可根据 A 发送的数据来做具体的事情。

  解耦的好处不用多说,设计模式中 单一职责原则 也表明我们希望每个实体(类、函数、模块等)能引起其改变的原因只有它自己。

  Subject:抽象主题,被观察者(Observable)的抽象,管理着众多观察者的实现,可以实现添加或删除观察者的功能。

  ConcreteSubject:具体主题,被观察者(Observable)的实现,通过该实现来向观察者发送通知。

  Observer:抽象观察者(Observer),观察者的抽象。一般是接口,实现该接口生成各种各样的观察者。

  ConcreteObserver:具体观察者,抽象观察者的具体实现,当被观察者发生变化时执行具体逻辑。

  这里定义的是 String 类型的,因为我的观察者是自定义 TextView,需要 String 来更新数据。setChanged() 这个是父类 Observable 中的方法,用来改变一个标记,表明数据已经更新。后面会根据该标记来决定是否通知所有观察者。notifyObservers(content)父类中的方法,该方调用所有观察者的 update() 方法实现数据的传递更新。

  要注意的是只有把所有被观察者使用 addObserver() 添加进来才会收到后续数据更新。

  两个变量 changed 和 obs。changed是数据是否变化的标记,主要作用是避免重复通知观察者。obs是一个自增长的数组,用来存放具体的观察者对象,也就是实现了 Observer 的实现类。

  这里有一个知识点:设计模式的 依赖倒置原则:面向接口编程而不是面向具体对象编程。这个 obs 数组存放的是接口类型而不是某个具体实现类型表明了这一点。

  那么这个标记什么时候才能为 true 呢?是在该类的子类中,也就是刚才例子中 DataSource 数据源类 updateData() 方法中首先调用 setChanged() 来设置标记为 true,表明数据即将进行更新。

  到这里 Observer(抽象观察者) 和 Observable(抽象被观察者)已经分析的差不多了,那么再结合刚才的例子来总结一下:

  DataSource 继承 Observable,是具体的被观察者。通过 notifyObservers() 方法传递具体数据来实现通知所有观察者,传递的具体逻辑是在父类中实现的。

  Observable 作为抽象被观察者实现具体的数据传递逻辑,其内部了一个标记和具体观察者列表,当数据发生变化时遍历该列表并通过调用 update() 方法来通知具体观察者实现不同的逻辑。

  通过以上对观察者模式的了解,四个主要角色 抽象观察者、具体观察者、抽象被观察者和具体观察者 起到了重要作用,而他们的运作是通过三个重要方法 注册观察者、解除注册、发送通知,那么分析 RecyclerView 也要从这几点入手。

  这个类继承了 Observable,看样子是一个被观察者实现类,为了验证一下,去看看 Observable 类。

  这个方法做的事情很简单,遍历 mObservers,获取其中的具体观察者并调用他们的 onChanged() 方法达到发送通知的目的。这个 mObservers 其实是一个 ArrayList,是由抽象被观察者(Observable)管理的列表,在刚才的 Observable 类中早就定义好了。

  在这里找到了发送通知的方法,遍历所有的具体观察者并调用他们的 onChanged() 方法,那么再看一下 onChanged() 方法的实现:

  可以看到是抽象类的空实现,那么就去找它的实现类,Ctrl+F 搜索 extends AdapterDataObserver。欧耶找到了,这就说明实现类也定义本类中。其实大多数实现类并不在本类中,这个小技巧也就是偶尔取巧用得上(#滑稽)。

  可以看到重写的 onChanged() 中调用了 requestLayout() 申请重新布局,至于怎样实现,感兴趣的同学可以参考我另一篇文章:

  这样四个角色都找齐了,三个方法只找到了发送通知的。还差注册和解除观察者的方法,这两个方法在 setAdapter 中所体现:

  观察者模式除了上文 java 包中的实现外,还有其它实现方式。话说回来,只要大方向不错,根据实际需求去定制设计模式和代码或许更好。

  notifyObservers():通知所有观察者的函数,可以自己实现来统一管理,也可以交给子类去实现。这里是抽象方法,由子类实现。

  综上,只有找到四个重要角色:抽象观察者、具体观察者、抽象被观察者和具体观察者,以及三个方法:注册、解除注册和发送通知,就可以理清观察者模式的应用了。

  观察者和被观察者之间建立的是一个抽象的耦合,被观察者并不需要了解每一个具体的观察者,但是可以通过共同的接口来控制它们。

  效率问题。如果观察者数量过多,遍历并按顺序执行它们的方产生效率问题。或者某个观察者所执行的代码过于繁琐,影响其他观察者信息或数据的接收。

  有关观察者模式的记录就先到这里,在学会这些知识后灵活运用才是最重要的。个人觉得没有最好的代码,只有最合适的代码。

0
0
0
0
0
0
0
0
下一篇:没有资料

网友评论 ()条 查看

姓名: 验证码: 看不清楚,换一个

推荐文章更多

热门图文更多

最新文章更多

关于联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助

声明:网站数据来源于网络转载,不代表站长立场,如果侵犯了你的权益,请联系站长删除。

CopyRight 2010-2016 科技创新信息网- All Rights Reserved