观察者模式是对象行为模式的一种类型。行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。《SOF设计模式》中是这样定义观察者模式的,Observer模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式有时也被成为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式(Dependents)。一般我更愿意称它为发布-订阅模式,在RxJava中就是采用订阅的方式来命名的,个人认为这种方式在举示例时也更容易理解。
以下任一情况下可以使用观察者模式 :
在Android开发或者其它GUI开发中,事件监听是最常见的一种观察者模式。举一个最常见的按钮Button点击事件,事件源是Button,在观察者模式中它就是一个Observable,监听器EventListener就是一个Observer,Button一旦注册了OnClickListener,点击Button就是触发OnClickListener中的OnClick方法。Button事件源(也就是Observable)有点击动作发生,就会被OnClickListener(Observer)监听到。也许平常开发过程中没有意识到设计模式,事实上设计模式已经应用到我们日常开发的方方面面了。
//按钮(Observer)注册监听器 btn.setOnClickListener(new MyListener()); //监听器(Observable) private class MyListener implements OnClickListener{ public void onClick(View v) { //TODO something } }
所有的GUI开发中,涉及到事件监听都是使用的观察者模式,也有人叫这种设置监听的方式叫做事件监听器模式,事实上它也是观察者模式的一种类型。
在Android中广播作为四大组件之一,也是最常用的组件之一,事实上广播机制就是使用的观察者模式实现的。在 Android Broadcast广播机制 这篇文章最后使用观察者模式对广播进行了简单的实现。
定义一个基类叫BroadcastReceiver,里面含有一个抽象方法,让所有继承该类的实现类都实现的一个广播接收的方法onReceiver。
public abstract class BroadcastReceiver { public abstract void onReceive(); }
定义一个Activity,实现相应的注册、注销以及发送广播的方法。
public class Activity { private List<BroadcastReceiver> list = new ArrayList<BroadcastReceiver>(); //注册广播 public void registerReceiver(BroadcastReceiverreceiver){ list.add(receiver); } //解除注册 public void unregisterReceiver(BroadcastReceiverreceiver){ list.remove(receiver); } //发送广播 public void sendBroadcast(){ for(BroadcastReceiverreceiver:list){ receiver.onReceive(); } } }
接下来我们定义MyReceiver01、MyReceiver02和MyReceiver03分别继承BroadcastReceiver,实现onReceiver方法,新建一个测试类MyActivity继承Activity。
public class MyActivity extends Activity { private MyReceiver01receiver01=new MyReceiver01(); private MyReceiver02receiver02=new MyReceiver02(); private MyReceiver03receiver03=new MyReceiver03(); public void method(){ //注册广播接受者 registerReceiver(receiver01); registerReceiver(receiver02); registerReceiver(receiver03); //注销receiver02 unregisterReceiver(receiver02); //发送广播 sendBroadcast(); } }
有关更详细的介绍可以查看 Android Broadcast广播机制 这篇博客。
RxJava 在 GitHub 主页上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库) 。RxJava的异步是通过观察者模式实现的,被观察者是Observable,观察者为Subscriber,也就是订阅者。在RxJava中观察者称为订阅者也许更具有实际意义,就好比订阅报纸吧,如果你订阅了报纸,报社才送报纸到你家里,只要订阅了报纸的人,报社都会送报。
下面是一个RxJava实现的简单示例:
Observable.create(new OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("hello world!"); } }).subscribe(new Subscriber<String>() { @Override public void onNext(String t) { System.out.println("onNext:"+t); } @Override public void onCompleted() { System.out.println("onCompleted"); } @Override public void onError(Throwable e) { } });
RxJava采用的是链式调用,没有任何嵌套,看上去逻辑更加简洁。针对Android开发在github上也有RxAndroid,现在很多博文都在讲RxJava和RxAndroid,它的欢迎程度可见一斑。
自定义观察者模式,首先必须明确如下职能:
接下来我们自定义一个观察者模式,首先抽象出观察者接口,代码如下:
public interface Observer { //接收被观察者的 信息 void update(Observableobj, Object arg); }
定义一个被观察者基类,代码如下:
public class Observable { //存储所有观察者对象 private List<Observer> list=new ArrayList<Observer>(); //添加观察者对象 public void addObserver(Observerobj){ if(obj!=null&&!list.contains(obj)){ list.add(obj); } } //移除观察者 public void deleteObserver(Observerobj){ list.remove(obj); } //有行为活动时通知观察者 public void notifyObservers(Object arg) { for(Observerobj:list){ obj.update(this, arg); } } //有行为活动时通知观察者 public void notifyObservers(){ notifyObservers(null); } }
然后定义观察者与被观察者的实现类
//观察者 public class FisherMan implements Observer { private String name; public FisherMan(String name){ this.name=name; } @Override public void update(Observableobj, Object arg) { System.out.println(name+" observed the fish is eating "+arg); } } //被观察者 public class Fish extends Observable { public String food; public Fish(String food){ this.food=food; } public void eating(String food){ notifyObservers(food); } public String toString() { return "Fish"; } }
接下来我们在在main函数中测试一下,代码如下:
public static void main(String[] args) { Fishfish=new Fish("food"); FisherManman01=new FisherMan("Man01"); FisherManman02=new FisherMan("Man02"); FisherManman03=new FisherMan("Man03"); fish.addObserver(man01); fish.addObserver(man02); fish.addObserver(man03); fish.deleteObserver(man02); fish.eating("food"); //Man01 observed the fish is eating food //Man03 observed the fish is eating food }
设计模式一般而言有23中,如果有时间希望可以将这23种设计模式一一记录下来学习。