1. 核心作用
观察者模式主要用于1:N的通知,当一个对象(目标对象Subject或Objservable)的状态变化时,他需要及时通知一系列的对象(观察者对象,Observer),令他们做出响应。
2. 通知观察者的方式:
*推:每次都把接通知以广播的方式发送给所有观察者,所有观察者只能被动的接受
*拉:观察者只要知道情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。
3. Demo
Demo:
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.html.CSS;
/*
* 观察者模式
*
*/
interface Observer{
void update(Subject subject);
}
//目标对象
class Subject{
//为了便于操作,定义为保护型
protected List<Observer> list = new ArrayList<Observer>();
public void registerObserver(Observer obs){
list.add(obs);
}
public void removeObserver(Observer obs){
list.remove(obs);
}
//通知所有观察者更新状态
public void notifyAllObserver(){
for(Observer obs : list){
obs.update(this);
}
}
}
class ConcreteSubject extends Subject{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
//主体目标对象发生变化,通知所有观察者
this.notifyAllObserver();
}
}
class ObserverA implements Observer{
private int myState;//让该值与目标对象保持一致
@Override
public void update(Subject subjects) {
myState = ((ConcreteSubject)subjects).getState();
}
public int getMyState(){
return myState;
}
public void setMyState(int myState){
this.myState = myState;
}
}
public class Observe {
public static void main(String[] args) {
//创建目标对象
ConcreteSubject cs = new ConcreteSubject();
//创建多个观察者
ObserverA ob1 = new ObserverA();
ObserverA ob2 = new ObserverA();
ObserverA ob3 = new ObserverA();
//将这三个观察者添加到观察者队伍中
cs.registerObserver(ob1);
cs.registerObserver(ob2);
cs.registerObserver(ob3);
//改变ConcreateSubject的状态
cs.setState(300);
//输出观察者的状态
System.out.println(ob1.getMyState());
System.out.println(ob2.getMyState());
System.out.println(ob3.getMyState());
}
}
观察者模式实现的另一种方式(依靠JDK提供的方法实现)
java.util.Observerable和java.util.Observer来实现观察者模式
Demo:
import java.util.Observable;
import java.util.Observer;
//目标对象
class ConcreteSubject2 extends Observable{
private int state;
public void setState(int state) {
this.state = state;
setChanged();//在Observable中提供的更改方法,表示目标对象已经做了更改
notifyObservers(state);//通知所有的观察者
}
public int getState() {
return state;
}
}
class ObserverB implements Observer{
private int myState;
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
@Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject2)o).getState();
}
}
public class Observer2 {
public static void main(String[] args) {
ConcreteSubject2 cs2 = new ConcreteSubject2();
ObserverB ob1 = new ObserverB();
ObserverB ob2 = new ObserverB();
ObserverB ob3 = new ObserverB();
//将上面三个观察者对象添加到目标对象subject中
cs2.addObserver(ob1);
cs2.addObserver(ob2);
cs2.addObserver(ob3);
//改变状态
cs2.setState(999);
System.out.println(ob1.getMyState());
System.out.println(ob2.getMyState());
System.out.println(ob3.getMyState());
}
}
4.应用场景
聊天系统中,服务器向所有客户端发送数据时(广播)
网络游戏中,服务器将客户端的状态进行分发
邮件订阅
Sertvlet中,监听器的实现
Android中的广播机制
JDK中的AWT中事物处理模型,基于观察者模式的委派事件(Delegation Event Modle)
事件源-------目标对象
事件监听器---观察者
京东商城,群发某件商品