前言
观察者模式(Observer Pattern)指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式属于行为型模式。
模式所涉及的角色
- 抽象主题(Subject):也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject):也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer):它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer):实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
代码实现
抽象通知者和具体通知者
public abstract class Subject {
protected List<Observer> observers = new ArrayList<>();
/**
* 增加观察者方法
* @param observer
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* 删除观察者方法
* @param observer
*/
public void detach(Observer observer) {
observers.remove(observer);
}
public abstract void notifyObserver();
}
public class ConcreteSubject extends Subject{
@Override
public void notifyObserver() {
System.out.println("具体通知者发生改变...");
for (Observer obs : observers) {
obs.update();
}
}
}
抽象观察者和具体观察者
public abstract class Observer {
public abstract void update();
}
public class ConcreteObserver extends Observer{
@Override
public void update() {
System.out.println("具体观察者做出响应...");
}
}
客户端
class ObserverPatternDemoApplicationTests {
@Test
void contextLoads() {
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.attach(new ConcreteObserver());
concreteSubject.notifyObserver();
}
}
事件委托方式
抽象通知者
public class Subject {
protected List<JdkEventListener> listeners = new ArrayList<>();
/**
* 添加监听器
* @param listener
*/
public void attach(JdkEventListener listener) {
listeners.add(listener);
}
public void notifyObserver(){
JdkEvent jdkEvent = new JdkEvent(this);
System.out.println("具体通知者发生改变...");
Iterator<JdkEventListener> iterator = listeners.iterator();
if (iterator.hasNext()){
JdkEventListener listener = iterator.next();
listener.handler(jdkEvent);
}
}
}
事件
public class JdkEvent extends EventObject {
public JdkEvent(Object source) {
super(source);
}
}
监听
public interface JdkEventListener extends EventListener {
void handler(JdkEvent jdkEvent);
}
具体观察者
public class ConcreteListener implements JdkEventListener{
@Override
public void handler(JdkEvent jdkEvent) {
System.out.println("具体观察者做出响应...");
}
}
客户端
class ObserverPatternDemoApplicationTests {
@Test
void contextLoads() {
Subject subject = new Subject();
subject.attach(new ConcreteListener());
subject.notifyObserver();
}
}
源码