记一次观察者模式的使用

作者: e4e52c116681 | 来源:发表于2018-12-25 19:34 被阅读26次

一、引入:

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

数据同步

把问题简化为下面7个类:
需求:数据在SongSubject中的改变,可以通知三个观察者,并同时更新数据

问题抽离

二、观察者模式:

一对多--一人提供信息(Subject),多人需求信息(Observer),信息体(T)
T发生改变时,由Subject统一提醒Observer


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

2.接口层:Subject接口:(被观察者)
public interface Subject<T> {
    /**
     * 观察者关联
     * @param o 待观察者(信息体)
     */
    void attach(Observer<T> o);

    /**
     * 观察者取消关联
     * @param o 待观察者()
     */
    void detach(Observer<T> 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<Song>{
    private List<Observer<Song>> mObservers = new ArrayList<>();//观察者对象集合
    private Song mSong;

    @Override
    public void attach(Observer<Song> observer) {
        mObservers.add(observer);
    }

    @Override
    public void detach(Observer<Song> observer) {
        mObservers.remove(observer);
    }

    @Override
    public void notifyObserver() {
        for (Observer<Song> 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<Song> {

    @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<Song> {
    @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<Song> {
    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.运行结果如下图
结果.gif
2.分析:

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

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

3.小结

设计模式还是在需要的时候能理解的清晰一些,干巴巴的看典例总感觉也就那样
最近在做个人播放器玩一下,整个体系挺大的,也比较碎,应该不能成文了,等完善发后源码吧

相关文章

  • 借助工厂模式构建不同的 Fragment

    还记的上篇文章 使用观察者模式解决单 Activity 与多个 Fragment 通信 中我使用了观察者模式暂时解...

  • 发布订阅模式(观察者模式)

    发布订阅模式(观察者模式) 发布订阅也叫观察者模式 发布 && 订阅 使用

  • RxJava观察者模式

    1.点击事件的观察者模式: 2.通用观察者模式: 3.RxJava的观察者模式 RxJava使用的是扩展的观察者模...

  • 记一次观察者模式的使用

    一、引入: 今天做播放器时碰到了一个小问题:有三个地方需要同一组数据,而且分属不同地方,如何同步?当然有很多方法可...

  • iOS与观察者模式(一)

    什么是观察者模式 观察者模式应该是我们日常中听说的最多,同时也是经常使用的设计模式。那么什么是观察者模式? 举一个...

  • php设计模式(4) 观察者模式(附加 不听话的观察者)

    php设计模式(4) 观察者模式(附加 不听话的观察者) 概述 代码实现 目标 和 观察者(使用了 php spl...

  • 观察者模式

    个人博客http://www.milovetingting.cn 观察者模式 模式介绍 观察者模式是一个使用率非常...

  • 设计模式之观察者模式(实例+Demo)

    你能从本文了解到如下几个方面:1. 什么是观察者模式?2. 如何使用观察者模式。 3. Java中的观察者模式的使...

  • 设计模式02-观察者者设计模式

    [toc] 设计模式02-观察者者设计模式 主要来源Head First设计模式(书)观察者设计模式是JDK中使用...

  • 观察者模式

    观察者模式介绍 观察者模式是日常使用比较广泛的一种模式,它可以很有效的解耦,将被观察者和观察者解耦,使他们之间的依...

网友评论

    本文标题:记一次观察者模式的使用

    本文链接:https://www.haomeiwen.com/subject/dwlqlqtx.html