定义
观察者模式又称为发布-订阅模式,模型-视图模式,源-监听器模式,它定义一种一对多的依赖关系,一个主题对象可以被多个观察者对象同时监听,使得主题对象的状态一旦发生改变时,所有依赖于它的对象都会得到通知并被自动更新、
使用场景
- 一个抽象模型包含两个方面的内容,其中一个方面依赖于另一个方面
- 其他一个或多个对象的变化依赖于另外一个对象的变化
- 需要实现广播机制的功能,无需知道具体的接收者,只需要分发广播,系统中感兴趣的对象会自动接收该广播
- 类似js中的下拉菜单多级联动的场景,多层嵌套使用形成一种链式触发机制,使得事件具备跨越两种观察者类型的通知
组成结构
- 抽象主题:被观察者对象,一般是一个接口或抽象类,主要是定义增加,删除,通知被观察者的方法
- 具体主题: 抽象主题的实现,当主题发出一个消息时,通知所有的被观察者做出响应。
- 抽象观察者:被通知对象
package com.lchtest.pattern.observer.general;
/**
* 抽象观察者
* @param <E>
*/
public interface IObserver<E> {
// 观察者接收到主题发出的消息后,做出相应的改变
void update(E event);
}
package com.lchtest.pattern.observer.general;
/**
* 抽象主题
*/
public interface ISubject<E> {
boolean attch(IObserver<E> observer);
boolean detach(IObserver<E> observer);
// 抽象主题发布一个消息
void notify(E event);
}
具体主题: 会保所有的观察者,一旦主题发生变化,就会通知到每个观察者对象(遍历调用每个观察者的update方法)
package com.lchtest.pattern.observer.general;
import java.util.ArrayList;
import java.util.List;
public class ConcreteSubject<E> implements ISubject<E> {
private List<IObserver<E>> observers = new ArrayList<>();
@Override
public boolean attch(IObserver observer) {
return !this.observers.contains(observer) && this.observers.add(observer);
}
@Override
public boolean detach(IObserver observer) {
return this.observers.remove(observer);
}
@Override
public void notify(E event) {
// 实现被观察者发出一个消息后,观察者自动做出响应
observers.forEach(observer -> observer.update(event));
}
}
package com.lchtest.pattern.observer.general;
/**
* 具体观察者
* @param <E>
*/
public class ConcreteObserver<E> implements IObserver<E> {
@Override
public void update(E event) {
System.out.println("recieve event:" + event);
}
}
package com.lchtest.pattern.observer.general;
public class Test {
public static void main(String[] args) {
// 被观察者:
ISubject<String> observable = new ConcreteSubject<>();
// 观察者
IObserver<String> observer = new ConcreteObserver<>();
// 把观察者注册到主题中
observable.attch(observer);
// 被观察者发出一个消息
observable.notify("hello");
}
}