在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
角色组成
抽象主题(Subject)
它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题(Concrete Subject)
将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有注册过的观察者发出通知。
抽象观察者(Observer)
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(Concrete Observer)
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
具体实现
抽象主题(被观察者)
public interface Subject {
/**
* 注册观察者
* @param observer
*/
void registerObserver(Observer observer);
/**
* 移除观察者
* @param observer
*/
void removeObserver(Observer observer);
/**
* 通知所有观察者
*/
void notifyAllObserver();
}
具体主题
public class SubjectImpl implements Subject {
private List<Observer> observerList = new ArrayList<>();
private String status;
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
@Override
public void notifyAllObserver() {
for (Observer observer : observerList) {
observer.process(status);
}
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
抽象观察者
public interface Observer {
void process(String status);
}
具体观察者
public class ObserverA implements Observer {
@Override
public void process(String status) {
System.out.println("A观察者收到了状态变更为【"+status+"】的通知");
}
}
public class ObserverB implements Observer {
@Override
public void process(String status) {
System.out.println("B观察者收到了状态变更为【"+status+"】的通知");
}
}
更改状态,来通知到其他观察者
SubjectImpl subject = new SubjectImpl();
//注册观察者A
Observer observerA = new ObserverA();
subject.registerObserver(observerA);
//注册观察者B
Observer observerB = new ObserverB();
subject.registerObserver(observerB);
subject.setStatus("进行中");
System.out.println("被观察者状态变为【进行中】,正在通知观察者们...");
//通知所有观察者
subject.notifyAllObserver();
被观察者状态变为【进行中】,正在通知观察者们...
A观察者收到了状态变更为【进行中】的通知
B观察者收到了状态变更为【进行中】的通知
总结
使用场景
- 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要被改变。
- 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。
- 观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。