您的位置:首页 > 其它

利用观察者模式(发布/订阅模式)制作一个“代替”广播的通知类

2016-11-28 18:09 591 查看
我们们通常会遇到这样一个问题,从MainActivity跳转到BActivity,在BActivity中我们做了一些操作,需要MainActivity更新界面,我们经常会用startActivityForResult来操作。但是如果是MainActivity —> ….. —>BActivity 中间跳转了多个Activity,用这个方法岂不是很复杂,当然有的朋友会在MainActivity类里面注册一个BroadcastReceiver,当需要MainActivity进行相关的操作时,只需要在BActivity里面sendBroadcast即可,当然这个办法也是可行的。但是像广播这种重量级选手,我们能不用还是尽量不用。

在这里我们将用观察者模式实现一个类似广播的通知类。

一、介绍

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。

抽象主题角色(被观察者):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

抽象消息订阅者角色(观察者):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

具体主题角色(被观察者):在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。

具体消息订阅者角色(观察者):该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

二、代码实现

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: