博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
记一次观察者模式的使用
阅读量:6585 次
发布时间:2019-06-24

本文共 3724 字,大约阅读时间需要 12 分钟。

一、引入:

今天做播放器时碰到了一个小问题:

有三个地方需要同一组数据,而且分属不同地方,如何同步?
当然有很多方法可以实现,本文主要讲观察者模式,也算是回虐它吧(曾经被它吊打...)
注意,本文使用的是测试代码,仅是模拟情况(Android上的使用道理是一致的,已实证)


把问题简化为下面7个类:

需求:数据在SongSubject中的改变,可以通知三个观察者,并同时更新数据


二、观察者模式:

一对多--一人提供信息(Subject),多人需求信息(Observer),信息体(T)

T发生改变时,由Subject统一提醒Observer


1.接口层:Observer接口:(观察者)
public interface Observer
{ /** * 更新 * @param t 观察变化的信息体 */ void update(T t);}复制代码

2.接口层:Subject接口:(被观察者)
public interface Subject
{ /** * 观察者关联 * @param o 待观察者(信息体) */ void attach(Observer
o); /** * 观察者取消关联 * @param o 待观察者() */ void detach(Observer
o); /** * 当信息体更新时调用,用于通知观察者 */ void notifyObserver();}复制代码

3.信息体(Song)
public class Song {    private String title;    private String singer;    private long seek;    public Song(String title, String singer, long seek) {        this.title = title;        this.singer = singer;        this.seek = seek;    }    //set、get、toString省略...}复制代码

4.信息提供者(被观察者实现类):
public class SongSubject implements Subject
{ private List
> mObservers = new ArrayList<>();//观察者对象集合 private Song mSong; @Override public void attach(Observer
observer) { mObservers.add(observer); } @Override public void detach(Observer
observer) { mObservers.remove(observer); } @Override public void notifyObserver() { for (Observer
o : mObservers) { o.update(mSong); } } /** * 设置信息--通知所有观察者 * @param song */ public void setSong(Song song) { mSong = song; this.notifyObserver(); }}复制代码

5.Pop观察者实现类
/** * 作者:张风捷特烈 * 时间:2018/12/24 0024:21:27 * 邮箱:1981462002@qq.com * 说明:观察者:Pop */public class PopPager implements Observer
{ @Override public void update(Song song) { //TODO:更新时的视图渲染 System.out.println("PopPager:" + song); }}复制代码

6.Fragment观察者实现类
/** * 作者:张风捷特烈 * 时间:2018/12/24 0024:21:27 * 邮箱:1981462002@qq.com * 说明:观察者:Fragment */public class HomeListFragment implements Observer
{ @Override public void update(Song song) { //TODO:更新时的视图渲染 System.out.println("HomeListFragment:" + song); }}复制代码

7.主页面观察者实现类

主要绑定逻辑在模仿的onCreate里,当然mpv里,你可以根据实际情况

/** * 作者:张风捷特烈 * 时间:2018/12/24 0024:21:27 * 邮箱:1981462002@qq.com * 说明:观察者:Activity */public class HomeActivity implements Observer
{ private int seek; public void onCreate() { SongSubject songSubject = new SongSubject(); PopPager popPager = new PopPager();//常见Pop HomeListFragment homeListFragment = new HomeListFragment();//创建Fragment songSubject.attach(this);//HomeActivity观察信息 songSubject.attach(homeListFragment);//homeListFragment观察信息 songSubject.attach(popPager);//popPager观察信息 Song song = new Song("勇气", "葛强丽", seek);//信息模拟 Timer timer = new Timer();//计时器轮训任务 timer.schedule(new TimerTask() { public void run() { song.setSeek(seek++);//修改信息 songSubject.setSong(song);//设置信息,通知所有观察者 } }, 0, 1000); } @Override public void update(Song song) { //TODO:更新时的视图渲染 System.out.println("HomeActivity:" + song); }}复制代码

8.启动类:
public class Boot {    public static void main(String[] args) {        HomeActivity activity = new HomeActivity();        activity.onCreate();    }}复制代码

三、观察者模式分析

1.运行结果如下图


2.分析:

单看结果好像并没有什么特色,但是请注意:

每次的印的三条数据分别来源于三个不同的类当你在update方法里用song对象控制视图显示时,只需要让被观察者更新数据就行了三个界面的信息会同步变化,这就是观察者模式优秀的地方毕竟实际中Pop弹框,Activity,Fragement分属不同类,能够这样统一变化会减少耦合复制代码

3.小结

设计模式还是在需要的时候能理解的清晰一些,干巴巴的看典例总感觉也就那样

最近在做个人播放器玩一下,整个体系挺大的,也比较碎,应该不能成文了,等完善发后源码吧

转载地址:http://kuano.baihongyu.com/

你可能感兴趣的文章
如何往Windows 2012 R2系统盘system32目录下面拷贝文件
查看>>
求职者需要知道的五个要点
查看>>
linux screen 命令详解
查看>>
Android Developer Tools 安装版本控制客户端
查看>>
Cocos Creator开发中的按钮节点的事件处理方法
查看>>
保护企业的Word文档
查看>>
作为前端Web开发者,这12条基本命令不可不会
查看>>
ActiveReports 报表应用教程 (16)---报表导出
查看>>
移除VMware View桌面中孤立的主机与桌面池
查看>>
vSphere与Workstation虚拟机交互的几种方法(一)
查看>>
Web组件 – 构建商业化应用的基石
查看>>
成功的力量,与共赢的理念。
查看>>
我的家庭私有云计划-15
查看>>
《.NET应用架构设计:原则、模式与实践》新书博客--试读-1.1-正确认识软件架构...
查看>>
基于Windows server 2008 R2和Windows7的企业环境的SSTP(或SSL) ***构建二
查看>>
使用python的分布式任务队列huey实现任务的异步化
查看>>
Facebook经济体
查看>>
Linux救命稻草--救援模式和单用户模式!
查看>>
博客园开博记录
查看>>
浅谈手机开发
查看>>