一、观察者模式概述
观察者模式主要用于 1 :N 的通知。当一个对象(目标对象 Subject 或 Observable)的状态变化时,它需要通知一系列对象(观察者对象 Observer),令它们做出响应。
通知观察者的方式:
(1)推
每次都会把通知以广播的方式发送给所有观察者,所有观察者只能被动接收。
(2)拉
观察者只要知道有情况即可。至于什么时候获取内容,获取哪些内容,都可以自主决定。
二、观察者模式示例代码
/**
* 观察者对象接口
* @author CL
*
*/
public interface Observer {
/**
* 更新主题
* @param subject
*/
void update(Subject subject); }
/**
* 主题对象(目标对象)
* @author CL
*
*/
public class Subject { protected List<Observer> list; public Subject() {
list = new ArrayList<Observer>();
} public void addObserver(Observer observer) {
list.add(observer);
} public void removeObserver(Observer observer) {
list.remove(observer);
} /**
* 通知所以观察者更新状态
*/
public void notifyAllObserver() {
for (Observer o : list) {
o.update(this);
}
} }
/**
* 具体的目标对象
* @author CL
*
*/
public class ConcreteSubject extends Subject { /**
* 状态
*/
private int state; public int getState() {
return state;
} public void setState(int state) {
this.state = state;
//若主题对象(目标对象)发生的状态发生改变,请通知所有观察者更新状态
this.notifyAllObserver();
} }
/**
* 观察者
* @author CL
*
*/
public class ObserverA implements Observer { private int myState; //myState需要和目标对象的state保持一致 @Override
public void update(Subject subject) {
myState = ((ConcreteSubject) subject).getState();
} public int getMyState() {
return myState;
} public void setMyState(int myState) {
this.myState = myState;
} }
测试:
/**
* 测试观察者模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//目标对象
ConcreteSubject sub = new ConcreteSubject(); //创建三个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA(); //将这三个观察者添加到目标对象subject的容器中
sub.addObserver(o1);
sub.addObserver(o2);
sub.addObserver(o3); //修改目标对象的状态值
sub.setState(100); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState()); System.out.println("----------------------"); //修改目标对象的状态值
sub.setState(10); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}
控制台输出:
100
100
100
----------------------
10
10
10
三、JDK 中提供类和方法实现观察者模式
import java.util.Observable; /**
* 目标对象
* @author CL
*
*/
public class ConcreteSubject extends Observable {
private int state; public int getState() {
return state;
} public void setState(int state) {
this.state = state; setChanged(); //表示目标对象已经更改状态 notifyObservers(); //通知所有观察者
} }
import java.util.Observable;
import java.util.Observer; /**
* 观察者对象
* @author CL
*
*/
public class ObserverA implements Observer { private int myState; @Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject) o).getState();
} public int getMyState() {
return myState;
} public void setMyState(int myState) {
this.myState = myState;
} }
测试:
/**
* 测试利用java.util.*包中的类Observable和接口Obsever实现的观察者模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//目标对象
ConcreteSubject sub = new ConcreteSubject(); //创建三个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA(); //将这三个观察者添加到目标对象subject的容器中
sub.addObserver(o1);
sub.addObserver(o2);
sub.addObserver(o3); //修改目标对象的状态值
sub.setState(666); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState()); System.out.println("----------------------"); //修改目标对象的状态值
sub.setState(123); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}
控制台输出:
666
666
666
----------------------
123
123
123
四、观察者模式常见开发应用场景
(1)手机APP中每天的推送广告;
(2)多人联机网络游戏中,服务器实时分发所有玩家的状态;
(3)Servlet 中监听器的实现;
(4)Android 中广播机制;
(5)JDK 的 AWT 事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model)
事件源:目标对象
事件监听器:观察者
(6)…………