场景
网站上很多人订阅了 java 主题的新闻,当有这个主题新闻时,就会将这些新闻发给所有订阅的人
- 把多个订阅者或客户称之为观察者;需要同步给多个订阅者的数据封装到对象中,称之为目标
- 观察者模式主要用于 1:N 的通知,当一个对象(目标对象Subject或Observable)的状态变化时,他需要及时告知一系列对象(观察者对象,Observer),令他们做出响应
通知观察者的方式
- 推—每次都会把通知以广播方式发送给所有观察者,所有观察者只能被动接受
- 拉—观察者只要直到有情况即可。至于什么时候获取内容,获取什么内容,都可以自主决定
结构
- 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
- 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
- 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
结构图
代码
public interface Observer {
void update(Subject subject);
}
public class ObserverA implements Observer {
private int myState; // myState需要跟目标对象的State值保持一致
@Override
public void update(Subject subject) {
this.myState = ((ConcreteSubject)subject).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int state) {
this.myState = state;
}
}
/**
* 消息发布,可以把它看作容器
*/
public class Subject {
private List<Observer> list = new ArrayList<>();
public void registerObserver(Observer observer){
this.list.add(observer);
}
public void removeObserver(Observer observer){
list.remove(observer);
}
/**
* 通知所有的观察者更新状态
*/
public void notifyAllObserver(){
for(Observer observer : list){
observer.update(this);
}
}
}
public class ConcreteSubject extends Subject {
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
//目标对象值发生了变化,通知所有的监听者
this.notifyAllObserver();
}
}
public class Client {
public static void main(String[] args){
//创建目标对象 消息发布者
ConcreteSubject subject = new ConcreteSubject();
//创建多个观察者 消息订阅者
ObserverA observer1 = new ObserverA();
ObserverA observer2 = new ObserverA();
ObserverA observer3 = new ObserverA();
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.registerObserver(observer3);
//改变 subject 状态
subject.setState(3000);
subject.notifyAllObserver();
//看看各个订阅者状态是否改变了
System.out.println(observer1.getMyState());
System.out.println(observer2.getMyState());
System.out.println(observer3.getMyState());
}
}
JDK自带的Observer
public class ConcreteSubject extends Observable {
private int state ;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state; //目标对象的状态发生了改变
setChanged();//表示目标对象已经改变了
notifyObservers(state);
}
}
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;
}
}
public class Client {
public static void main(String[] args){
//创建目标对象 消息发布者
ConcreteSubject subject = new ConcreteSubject();
//创建多个观察者 消息订阅者
ObserverA observer1 = new ObserverA();
ObserverA observer2 = new ObserverA();
ObserverA observer3 = new ObserverA();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.addObserver(observer3);
//改变 subject 状态
subject.setState(3000);
subject.notifyObservers();
//看看各个订阅者状态是否改变了
System.out.println(observer1.getMyState());
System.out.println(observer2.getMyState());
System.out.println(observer3.getMyState());
}
}