概念
定义对象间的一对多的关系,使得当一个对象改变状态,所有依赖于它的对象都会得到通知并自动更新。优点是被观察者和观察者是抽象耦合,提高系统灵活性,缺点是开发调试变复杂,而且java消息通知默认是顺序执行,一个观察者卡顿会影响整体执行效率,所以一般采取异步形式。
使用场景
- 关联行为场景(不是组合)
- 事件多级触发场景
- 跨系统消息交换,如消息队列,事件总线的处理机制
实现方式
- Subject —— 抽象主题:被观察者角色(Observable),将所有观察者对象的引用保存在集合中,提供可以增加删除观察者的接口。
- ConcreteSubject —— 具体主题 具体被观察者
- Observer —— 抽象观察者 定义一个更新接口,使得在在主题状态改变时及时通知自己更新状态。
- ConcreteObserver —— 具体观察者 Observer 和 Observable是JDK的内置类型,因此,我们可以直接编写具体实现类
/**
* 抽象被观察者
**/
interface Observable {
//注册观察者
void registerObserver(Observer observer);
//解除绑定观察者
void unRegisterObserver(Observer observer);
//更新数据
void notifyObservers();
}
/**
* 抽象观察者
*/
interface Observer {
void update(Observable observable, Object value);
}
/**
* 具体被观察者
**/
public class MyView implements Observable {
List<Observer> observerList;
private int progress;
public MyView() {
this.observerList = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
if (observerList.contains(observer)) {
return;
}
observerList.add(observer);
}
@Override
public void unRegisterObserver(Observer observer) {
int i = observerList.indexOf(observer);
if (i >= 0) {
observerList.remove(observer);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observerList) {
observer.update(this, progress);
}
}
public void setProgress(int progress) {
this.progress = progress;
notifyObservers();
}
}
/**
* 具体观察者
*/
public class ProgressListener implements Observer {
@Override
public void update(Observable observable, Object value) {
System.out.println("progress = " + value);
}
}
public static void main(String[] args) {
MyView myView = new MyView();
Observer progressListener = new ProgressListener();
myView.registerObserver(progressListener);
myView.setProgress(10);
}