版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/89879269
1. 定义
又叫发布-订阅模式、模型-视图模式、源-监听器模式或从属者模式。定义了对象的一对多依赖,让多个观察者对象同时监听某一个主题对象。当主题对象改变状态时,所有依赖者会收到通知并更新
- 主题:管理状态,在状态发生变化时,通知观察者
- 推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要
- 拉模型:如果观察者需要更具体的信息,由观察者主动到主题对象中获取
- 观察者
- 在注册/订阅了主题后,可以收到状态的更新
- 取消订阅后,不会收到状态的更新
2. 实现
- 抽象观察者:提供更新接口,在主题发生改变时更新
- 具体观察者:订阅具体的主题,协调主题的状态
- 抽象主题:注册、去除、通知观察者
- 具体主题:保存具体状态
(1)主题
package ObservePattern;
import java.util.List;
/**
*抽象主题
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 去除观察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知观察者,拉数据
*/
public void notifyObserver();
/**
* 通知观察者,推数据
* @param status
*/
public void notifyObserver(Object status);
}
package ObservePattern;
import java.util.ArrayList;
import java.util.List;
/**
* 具体的主题
*/
public class MainSubject implements Subject{
//观察者列表
private List<Observer> observers;
//具体数据
private Object status;
public MainSubject(){
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
for (Observer observer:
observers) {
observer.update();
}
}
@Override
public void notifyObserver(Object status) {
for (Observer observer:
observers) {
observer.update(status);
}
}
//获取数据
public Object getStatus() {
return status;
}
//数据发生改变
public void change(Object status){
this.status = status;
System.out.println("拉数据");
notifyObserver();
System.out.println("推数据");
notifyObserver(status);
}
}
(2)观察者
package ObservePattern;
/**
* 抽象观察者
*/
public interface Observer {
/**
* 取消订阅主题
*/
public void cancel();
/**
* 自己获取数据
* @param
*/
public void update();
/**
* 直接获取数据
* @param status
*/
public void update(Object status);
}
package ObservePattern;
/**
* 具体观察者A
*/
public class ObserverA implements Observer {
//具体状态
private Object status;
//具体主题
private Subject subject;
//订阅主题
public ObserverA(Subject subject){
this.subject = subject;
subject.registerObserver(this);
}
//取消订阅
@Override
public void cancel() {
subject.removeObserver(this);
}
@Override
public void update() {
if (subject instanceof MainSubject){
this.status = ((MainSubject) subject).getStatus();
System.out.println("自己拉数据,A知道状态改变了");
}
}
@Override
public void update(Object status) {
this.status = status;
System.out.println("主题推数据,A知道状态改变了");
}
}
package ObservePattern;
/**
* 具体观察者B
*/
public class ObserverB implements Observer {
//具体状态
private Object status;
//具体主题
private Subject subject;
//订阅主题
public ObserverB(Subject subject){
this.subject = subject;
subject.registerObserver(this);
}
//取消订阅
@Override
public void cancel() {
subject.removeObserver(this);
}
@Override
public void update() {
if (subject instanceof MainSubject){
this.status = ((MainSubject) subject).getStatus();
System.out.println("自己拉数据,B知道状态改变了");
}
}
@Override
public void update(Object status) {
this.status = status;
System.out.println("主题推数据,B知道状态改变了");
}
}
(3)测试
package ObservePattern;
public class Test {
public static void main(String[] args) {
Subject subject = new MainSubject();
Observer observerA = new ObserverA(subject);
Observer observerB = new ObserverB(subject);
((MainSubject) subject).change("test");
}
}
3. 特点
- 可以随时添加、删除观察者,无需修改主题
- 可以独立使用主题或观察者
- 有多个观察者时,通知顺序不一定相同
4. JAVA内置的支持
- 主题——Observable类:发送通知
- setChanged():标记状态改变
- notifyObservers():通知,拉数据
- notifyObservers(xxx):发送数据和通知,推数据
- 观察者——Observer类:接收通知
- update(Observale x):主题
- update(Observale x,xxx):主题和数据