利用观察者模式(发布/订阅模式)制作一个“代替”广播的通知类
2016-11-28 18:09
591 查看
我们们通常会遇到这样一个问题,从MainActivity跳转到BActivity,在BActivity中我们做了一些操作,需要MainActivity更新界面,我们经常会用startActivityForResult来操作。但是如果是MainActivity —> ….. —>BActivity 中间跳转了多个Activity,用这个方法岂不是很复杂,当然有的朋友会在MainActivity类里面注册一个BroadcastReceiver,当需要MainActivity进行相关的操作时,只需要在BActivity里面sendBroadcast即可,当然这个办法也是可行的。但是像广播这种重量级选手,我们能不用还是尽量不用。
在这里我们将用观察者模式实现一个类似广播的通知类。
一、介绍
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。
抽象主题角色(被观察者):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象消息订阅者角色(观察者):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体主题角色(被观察者):在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
具体消息订阅者角色(观察者):该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
二、代码实现
1. 抽象主题角色
2.抽象消息订阅者
3.具体主题角色(被观察者)
4.具体消息订阅者角色(观察者)
5.接下来再写一个订阅模式管理类,方便调用
6.使用
再看一下调用
Demo地址:
https://code.csdn.net/chengliang0315/observerdemo/tree/master
http://download.csdn.net/detail/chengliang0315/9696796
在这里我们将用观察者模式实现一个类似广播的通知类。
一、介绍
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。
抽象主题角色(被观察者):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象消息订阅者角色(观察者):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体主题角色(被观察者):在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
具体消息订阅者角色(观察者):该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
二、代码实现
1. 抽象主题角色
package com.example.observerdemo.observer; /** * 被观察者 */ public interface IObservable { /** * 向消息订阅队列添加订阅者 */ void deleteObserver(IObserver observer); /** * 删除指定订阅者 */ void addObserver(IObserver observer); /** * 通知消息订阅队列里的每一个订阅者 * @param data 给订阅者传递的参数 * @param flag 标示 */ void notifyObservers(Object data,int flag); }
2.抽象消息订阅者
package com.example.observerdemo.observer; /** * 消息订阅者(观察者) */ public interface IObserver { /** * 当消息发布者发布消息的时候调用该方法 * @param observable 消息发布者 * @param msg 发布的消息内容 * @param flag 消息的类型标记 */ void onMessageReceived(IObservable observable, Object msg, int flag); }
3.具体主题角色(被观察者)
package com.example.observerdemo.observer; import java.util.ArrayList; import java.util.List; /** * 被观察者的具体化,该类负责给观察者发送消息 * 参考 {@link java.util.Observable} */ public class EventObservable implements IObservable{ /** * 存放消息订阅者 */ List<IObserver> observers = new ArrayList<IObserver>(); public EventObservable() { } /** * 向消息订阅队列添加订阅者 */ @Override public void addObserver(IObserver observer) { if (observer == null) { throw new NullPointerException("EventObservable == null"); } synchronized (this) { if (!observers.contains(observer)) { observers.add(observer); } } } /** * 获得订阅者的数量 */ public int countObservers() { return observers.size(); } /** * 删除指定订阅者 */ @Override public synchronized void deleteObserver(IObserver observer) { observers.remove(observer); } /** * 删除所有订阅者. */ public synchronized void deleteObservers() { observers.clear(); } /** * 通知消息订阅队列里的每一个订阅者 */ public void notifyObservers(int flag) { notifyObservers(null,flag); } /** * 通知消息订阅队列里的每一个订阅者 * @param data 给订阅者传递的参数 */ @SuppressWarnings("unchecked") @Override public void notifyObservers(Object data,int flag) { int size = 0; IObserver[] arrays = null; synchronized (this) { size = observers.size(); arrays = new IObserver[size]; observers.toArray(arrays); } if (arrays != null) { for (IObserver observer : arrays) { observer.onMessageReceived(this, data,flag); } } } }
4.具体消息订阅者角色(观察者)
public class EventObserver implements IObserver{ /** * 重写自 IObserver 的方法 * @param observable 消息发布者 * @param msg 发布的消息内容 * @param flag 消息的类型标记 */ @Override public void onMessageReceived(IObservable observable, Object msg, int flag) { switch (flag) { case ObserverHolder.STAFF_ADD: // 添加员工 Log.e("DEVICE_ADD", (String) msg); count++; break; case ObserverHolder.STAFF_DELETE: //删除员工 Log.e("DEVICE_DELETE", (String) msg); count--; break; } txtContent.setText("还有"+count+"位员工"); } }
5.接下来再写一个订阅模式管理类,方便调用
package com.example.observerdemo.observer; /** * 订阅模式管理类 */ public class ObserverHolder { /** * 添加员工 */ public static final int STAFF_ADD = 0; /** * 删除员工 */ public static final int STAFF_DELETE = 1; /** * 更改员工信息 */ public static final int STAFF_ALTER = 2; private static ObserverHolder instance; private EventObservable observable; private ObserverHolder() { observable = new EventObservable(); } public static ObserverHolder getInstance() { if (instance == null) { synchronized (ObserverHolder.class) { if (instance == null) { instance = new ObserverHolder(); } } } return instance; } /** * 将消息接收者注册进来 * (如果将Activity作为订阅者在此注册的时候,切记在onDestroy()里面移除注册,否则可能导致内存泄露) * @param observer */ public void register(IObserver observer){ observable.addObserver(observer); } /** * 将消息接收者移除注册 */ public void unregister(IObserver observer){ observable.deleteObserver(observer); } /** * 给订阅者发生消息 * @param data */ public void notifyObservers(String data,int flag){ observable.notifyObservers(data,flag); } }
6.使用
EventObserver observer = new EventObserver(); ObserverHolder.getInstance().register(observer); //注册 ObserverHolder.getInstance().unregister(observer); //不用的时候释放注册
再看一下调用
public void onClick(View view) { switch (view.getId()) { case R.id.btn_add: ObserverHolder.getInstance().notifyObservers("添加员工",ObserverHolder.STAFF_ADD); break; case R.id.btn_delete: ObserverHolder.getInstance().notifyObservers("删除员工",ObserverHolder.STAFF_DELETE); break; } }
Demo地址:
https://code.csdn.net/chengliang0315/observerdemo/tree/master
http://download.csdn.net/detail/chengliang0315/9696796
相关文章推荐
- 自实现观察者模式(发布/订阅模式)的一个隐藏bug
- 观察者模式 VS 发布/订阅(广播)
- 十六 设计模式之观察者模式(发布订阅模式)
- 利用redis的订阅和发布来实现实时监控的一个DEMO(Python版本)
- 观察者模式与发布/订阅模式的区别
- 【GOF23设计模式】_观察者模式_广播机制_消息订阅_网络游戏对战原理_自带类与接口JAVA251-252
- 观察者模式和发布/订阅模式的区别
- 观察者模式之二 -发布 订阅模式
- C++之观察者模式(订阅-发布模式)
- java笔记--设计模式之观察者(订阅/发布)模式
- Android用观察者模式代替广播通知刷新界面
- java设计模式-观察者模式(广播机制,消息订阅)
- 观察者模式:消息的发布与订阅
- 观察者(发布-订阅)模式浅析
- 观察者模式与发布/订阅模式区别
- 观察者(发布订阅)模式 与 委托事件
- 利用redis的订阅和发布来实现实时监控的一个DEMO(Python版本)
- 设计模式初探-观察者模式(OBSERVER)又称发布-订阅(Publish-Subscribe)依赖(Dependents)
- 观察者模式和发布/订阅模式的区别
- redis的观察者模式----------发布订阅功能