关于java 的 观察者 模式 的基本概念和 使用可以看: Java_观察者模式(Observable和Observer)
补充:最近还有 “Rxjava” 这个 比较火的 基于观察者模式的异步架构,但我想先研究好观察者源码再去引入Rxjava 到我的工程中。
本文主要是进行观察者 的一些简单的使用分析,如有错误,还望指教。
一、为什么要使用观察者?
如果只是简单的需要回调与通知,完全可以写一个简单 的回调方式 ,例子如下:
一个要 “被观察”的类,代码如下
public class UpdateSrc {
Callback callback = null;
public void changeSrc(String data){
System.out.println("简单 被观察者 获取到新数据->"+data);
callback.onCallback(data);
}
public void setCallBack(Callback callback){
this.callback = callback;
}
public static interface Callback{
public void onCallback(Object data);
}
}
一个 “观察数据”的类,如下:
public class UpdateObserver {
void setDataSrc(UpdateSrc src){
src.setCallBack(new UpdateSrc.Callback() {
@Override
public void onCallback(Object data) {
System.out.println("简单 观察者 获取到数据->"+data);
}
});
}
}
测试代码如下:
UpdateSrc src = new UpdateSrc();
UpdateObserver observer = new UpdateObserver();
observer.setDataSrc(src);
src.changeSrc("数据一");
src.changeSrc("数据二");
src.changeSrc("数据三");
src.changeSrc("数据四");
测试结果如下:
简单 被观察者 获取到新数据->数据一
简单 观察者 获取到数据->数据一
简单 被观察者 获取到新数据->数据二
简单 观察者 获取到数据->数据二
简单 被观察者 获取到新数据->数据三
简单 观察者 获取到数据->数据三
简单 被观察者 获取到新数据->数据四
简单 观察者 获取到数据->数据四
看起来简单好用又没啥大毛病,那么为啥java还要给大伙儿提供 Observer 接口 和 Observable 类呢?目前仅仅看代码模式可以看到两大优势,当然欢迎各位小伙伴留言补充,我会再依次看情况整理添加上来
一、一定程度的解耦:
首先回顾我写的“UpdateObserver”类,发现了了么?它很容易就把“UpdateSrc” 类加进来了,一部小心就造成代码耦合了,哪天你要删除 “UpdateSrc” 类,就也得修改“UpdateObserver”类的代码。
如果使用观察模式呢?
可以看如下代码:
被观察者的代码
import java.util.Observable;
public class MyObservable extends Observable {
public void setData(String data){
System.out.println("被观察者 获取到新数据->"+data);
setChanged();
notifyObservers(data);
}
}
观察者的代码如下
import java.util.Observable;
import java.util.Observer;
public class MyObserver implements Observer{
public MyObserver(Observable observable) {
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者 获取到的数据->"+arg);
}
}
看上述代码,没有耦合引用到“MyObservable”类 的地方
测试代码如下:
MyObservable observable = new MyObservable();
MyObserver observer = new MyObserver(observable);
observable.setData("数据一");
observable.setData("数据二");
observable.setData("数据三");
测试结果如下:
被观察者 获取到新数据->数据一
观察者 获取到的数据->数据一
被观察者 获取到新数据->数据二
观察者 获取到的数据->数据二
被观察者 获取到新数据->数据三
观察者 获取到的数据->数据三
解耦总结:实现Observer ,继承 Observable,可以减低耦合,当然,如果硬是把上述的第一种情况也做到低耦合,也不是不可以,将 UpdateSrc.Callback 这个 内部类 改成一个独立类,但是这样一来,不就和sdk提供的Observer 更相似了么?直接使用Observer 不更简单省事儿?
第二、比较容易实现“多对多的callback模式”
1、”多对一”的情况,数个observable有数据的时候,要传递数据到同一个observer
2、“一对多”的情况, 一个observable有数据的时候,要传递给数个observer
3、“多对多”的情况,数据个obervable有数据的时候,要传递给数个observer
现在我们基于第三种场景来改代码
被观察者代码如下
public class MyObservable extends Observable {
private String mName = null;
public MyObservable(String name) {
mName = name;
}
@Override
public String toString() {
return mName;
}
public void setData(String data) {
System.out.println(mName + " 获取到新数据->" + data);
setChanged();
notifyObservers(data);
}
}
观察者的代码如下:
public class MyObserver implements Observer {
private String mName = null;
public MyObserver(String name) {
mName = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(mName + " 获取到的数据->" + arg + " 数据来源是->" + o);
}
}
测试代码如下
MyObserver myObserver1 = new MyObserver("观察者1");
MyObserver myObserver2 = new MyObserver("观察者2");
MyObserver myObserver3 = new MyObserver("观察者3");
MyObservable myObservable1 = new MyObservable("被观察者1");
MyObservable myObservable2 = new MyObservable("被观察者2");
MyObservable myObservable3 = new MyObservable("被观察者3");
myObservable1.addObserver(myObserver1);
myObservable1.addObserver(myObserver2);
myObservable1.addObserver(myObserver3);
myObservable1.setData("数据一");
myObservable2.addObserver(myObserver1);
myObservable2.addObserver(myObserver2);
myObservable2.addObserver(myObserver3);
myObservable2.setData("数据二");
myObservable3.addObserver(myObserver1);
myObservable3.addObserver(myObserver2);
myObservable3.addObserver(myObserver3);
myObservable3.setData("数据3");
运行结果如下:
被观察者1 获取到新数据->数据一
观察者3 获取到的数据->数据一 数据来源是->被观察者1
观察者2 获取到的数据->数据一 数据来源是->被观察者1
观察者1 获取到的数据->数据一 数据来源是->被观察者1
被观察者2 获取到新数据->数据二
观察者3 获取到的数据->数据二 数据来源是->被观察者2
观察者2 获取到的数据->数据二 数据来源是->被观察者2
观察者1 获取到的数据->数据二 数据来源是->被观察者2
被观察者3 获取到新数据->数据3
观察者3 获取到的数据->数据3 数据来源是->被观察者3
观察者2 获取到的数据->数据3 数据来源是->被观察者3
观察者1 获取到的数据->数据3 数据来源是->被观察者3
总结:一定程度上来讲,观察者模式的使用就比普通的设置interface callback 类要强大一些,但是,我们通过阅读observabel 类可以知道,观察者是产生了一定的额外代码消耗的,我们更应该依照自己面对的场景选择合适的方法。
补充:欢迎各位小伙伴留言交流,提出更多的场景,我得以补充文章内容,大家相互学习。