观察者模式定义了一对多的依赖,当被观察者发生改变时,依赖于它的所有观察者会收到通知并自动更新,下面我们以百度摇号短信提醒举例说明,相信大家都有切身体会吧,下面看图:
如图所示,短信提醒系统就是被观察者,每个摇号者都是观察者。观察者需要向被观察者订阅,才能收到被观察者发出的通知,同时观察者也可以取消订阅。
观察者模式包括两个接口、两个实现类,如下图:
Observable接口(短信提醒系统)可以添加观察者、注销观察者、通知所有的观察者,它有许多个观察者(摇号者) 。当收到Observable的通知时,具体的观察者会更新自己的状态,比如得知中签后,有的人会买车上号牌、有的人会把号牌出租。
下面我们写代码说明,首先是被观察者接口、观察者接口。
public interface Observable {
/**
* 注册一个观察者
*
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除一个观察者
*
* @param observer
*/
public void unRegisterObserver(Observer observer);
/**
* 通知所有的观察者
*
* @param WinningNumbers WinningNumbers 是摇中的编号
*/
public void notifyObservers(String WinningNumbers);
}
public interface Observer {
/**
* 得知中签后该做什么
*/
public void doWhatAfterWon();
}
下面是摇号短信提醒实现类。
public class YaohaoSMSReminder implements Observable {
private List<Observer> observers = new ArrayList<Observer>();
//中签编号
private String mWinningNumbers;
@Override
public void registerObserver(Observer observer) {
if (observer != null) {
observers.add(observer);
}
}
@Override
public void unRegisterObserver(Observer observer) {
if (observer != null) {
observers.remove(observer);
}
}
@Override
public void notifyObservers(String WinningNumbers) {
if (observers != null) {
for (Observer observer : observers) {
observer.doWhatAfterWon(WinningNumbers);
}
}
}
public void setWinningNumbers(String winningNumbers) {
mWinningNumbers = winningNumbers;
}
}
下面模拟两个摇号者。
package designPattern;
import android.util.Log;
/**
* Created by liuliu on 2017/6/9.
*/
public class Yaohao1 implements Observer {
private static final String myYaohaoNumbers = "1234567890";
private Observable mYaohaoSMSReminder;
public Yaohao1(Observable observable) {
mYaohaoSMSReminder = observable;
mYaohaoSMSReminder.registerObserver(this);
}
@Override
public void doWhatAfterWon(String WinningNumbers) {
if (myYaohaoNumbers.equals(WinningNumbers)) {
Log.i("Yaohao1 中签了", "买车上号牌");
} else {
Log.i("Yaohao1 未中签,本期中签编号:", WinningNumbers);
}
}
}
package designPattern;
import android.util.Log;
/**
* Created by liuliu on 2017/6/9.
*/
public class Yaohao2 implements Observer {
private static final String myYaohaoNumbers = "1234567891";
private Observable mYaohaoSMSReminder;
public Yaohao2(Observable observable) {
mYaohaoSMSReminder = observable;
mYaohaoSMSReminder.registerObserver(this);
}
@Override
public void doWhatAfterWon(String WinningNumbers) {
if (myYaohaoNumbers.equals(WinningNumbers)) {
Log.i("Yaohao2 中签了", "把号牌租出去");
} else {
Log.i("Yaohao2 未中签,本期中签编号:", WinningNumbers);
}
}
}
下面是测试代码。
package designPattern;
/**
* Created by liuliu on 2017/6/9.
*/
public class TestObserverAndObservable {
public static void main(String[] args) {
YaohaoSMSReminder smsReminder = new YaohaoSMSReminder();
Yaohao1 yaohao1 = new Yaohao1(smsReminder);
Yaohao2 yaohao2 = new Yaohao2(smsReminder);
smsReminder.setWinningNumbers("1234567890");
smsReminder.notifyObservers("1234567890");
}
}
测试结果:
Yaohao1 中签了,买车上号牌
Yaohao2 未中签,本期中签编号:1234567890
此外,Java SDK中已经帮我们实现了观察者模式,借助于java.util.Observable和java.util.Observer,下面我们使用Java内置Observable、Observer进行测试。
被观察者(摇号短信提醒系统):
package com.example;
import java.util.Observable;
/**
* Created by liuliu on 2017/6/9.
*/
public class YaohaoSmsReminder extends Observable {
private String mWinningNumbers;
public void setWinningNumbers(String winningNumbers) {
mWinningNumbers = winningNumbers;
setChanged();
notifyObservers();
}
public String getWinningNumbers() {
return mWinningNumbers;
}
}
观察者1、2:
package com.example;
import java.util.Observable;
import java.util.Observer;
/**
* Created by liuliu on 2017/6/9.
*/
public class Yaohao1 implements Observer {
private static final String myYaohaoNumbers = "1234567890";
@Override
public void update(Observable observable, Object o) {
YaohaoSmsReminder reminder = (YaohaoSmsReminder) observable;
String numbers = reminder.getWinningNumbers();
if (myYaohaoNumbers.equals(numbers)) {
System.out.println("Yaohao1中签了");
} else {
System.out.println("Yaohao1未中签");
}
}
}
package com.example;
import java.util.Observable;
import java.util.Observer;
/**
* Created by liuliu on 2017/6/9.
*/
public class YaoHao2 implements Observer{
private static final String myYaohaoNumbers = "1234567891";
public void update(Observable observable, Object o) {
YaohaoSmsReminder reminder = (YaohaoSmsReminder) observable;
String numbers = reminder.getWinningNumbers();
if (myYaohaoNumbers.equals(numbers)) {
System.out.println("Yaohao2中签了");
} else {
System.out.println("Yaohao2未中签");
}
}
}
测试类:
package com.example;
public class MyClass {
public static void main(String[] args) {
YaohaoSmsReminder reminder = new YaohaoSmsReminder();
Yaohao1 yaohao1 = new Yaohao1();
YaoHao2 yaoHao2 = new YaoHao2();
reminder.addObserver(yaohao1);
reminder.addObserver(yaoHao2);
reminder.setWinningNumbers("1234567890");
}
}
测试结果:
Yaohao2未中签
Yaohao1中签了
使用Java内置的类实现观察者模式,代码非常简洁,对于addObserver,removeObserver,notifyObservers都已经为我们实现了。
希望大家批评指正,Android开发交流群:576500546