行为型-观察者模式
文章目录
- 基本概念
- 定义
- 使用场景
- 代码实现
- 延伸阅读
- java监听机制
- spring监听机制
基本概念
定义
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。
观察者模式包含以下几个核心角色:
主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。
使用场景
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。通过这种事件触发的机制,将观察者和被观察者进行解耦。
注意事项:
1、JAVA 中已经有了对观察者模式的支持类。(Java中EventObject、EventListener)
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
代码实现
主题接口
/**
* 抽象主题(抽象被观察者角色)
*/
public interface Subject {
/**
* 所有抽象观察者角色的集合
*/
List<Observer> observerList = Lists.newArrayList();
/**
* 注册观察者
* @param observer
*/
default void addObserver(Observer observer){
observerList.add(observer);
}
/**
* 取消注册
* @param observer
*/
default void removeObserver(Observer observer){
observerList.remove(observer);
}
/**
* 通知所有观察者
* @param content
*/
default void notifyAllObserver(String content){
for (Observer observer: observerList){
observer.recvMsg(content);
}
}
}
观察者接口
/**
* 观察者
*/
public interface Observer {
void recvMsg(String content);
}
具体被观察者
@Data
public class ConcreteSubject implements Subject<Observer> {
private String msg;
/**
* 发送通知
*/
public void sendMsg(){
System.out.println("ConcreteSubject send msg: " + this.msg);
notifyAllObserver(msg);
}
}
具体观察者
public class ConcreteObserver implements Observer {
@Override
public void recvMsg(String content) {
System.out.println("ConcreteObserver recv msg:" + content);
}
}
测试
public class ObserverTest {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.setMsg("important msg");
concreteSubject.addObserver(new ConcreteObserver());
concreteSubject.sendMsg();
}
}
延伸阅读
java监听机制
一、创建事件对象
public class MusicEvent extends EventObject {
public static final int STATE_OPEN = 1;
public static final int STATE_CLOSE = -1;
/**
* 状态
*/
private int state;
/**
* Constructs a prototypical Event.
*
* @param source the object on which the Event initially occurred
* @throws IllegalArgumentException if source is null
*/
public MusicEvent(Object source) {
super(source);
}
public MusicEvent(Object source, int state) {
super(source);
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
二、创建监听器
public interface MusicListener extends EventListener {
void play(MusicEvent musicEvent);
}
CloseMusicListener实现
public class CloseMusicListener implements MusicListener{
@Override
public void play(MusicEvent musicEvent) {
if(musicEvent.getState() == MusicEvent.STATE_CLOSE){
System.out.println("CloseMusicListener play: stop dance");
}
}
}
OpenMusicListener实现
public class OpenMusicListener implements MusicListener{
@Override
public void play(MusicEvent musicEvent) {
if(musicEvent.getState() == MusicEvent.STATE_OPEN){
System.out.println("OpenMusicListener play: let us go dancing!");
}
}
}
三、定义事件源,管理监听器
public class EventSource {
// 监听器列表,监听器注册入此列表
public List<MusicListener> musicListenerList = new ArrayList<>();
// 注册监听器
public void addMusicListener(MusicListener musicListener) {
musicListenerList.add(musicListener);
}
// 取消注册
public void removeMusicListener(MusicListener musicListener) {
musicListenerList.remove(musicListener);
}
// 接收外部事件
public void notifyMusicListener(MusicEvent musicEvent) {
for (MusicListener musicListener : musicListenerList){
musicListener.play(musicEvent);
}
}
}
四、测试
public class MusicEventTest {
public static void main(String[] args) {
EventSource eventSource = new EventSource();
eventSource.addMusicListener(new OpenMusicListener());
eventSource.addMusicListener(new CloseMusicListener());
eventSource.notifyMusicListener(new MusicEvent("开门事件", MusicEvent.STATE_OPEN));
}
}
spring监听机制
一、创建事件对象,继承ApplicationEvent
@EqualsAndHashCode(callSuper = true)
public class MyEvent extends ApplicationEvent {
private String context;
public MyEvent(Object source) {
super(source);
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
}
二、定义监听器,实现ApplicationListener
MyApplication1
public class MyApplication1 implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent myEvent) {
System.out.println("MyApplication1 event:" + myEvent.getContext());
}
}
MyApplication2
public class MyApplication2 implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent myEvent) {
System.out.println("MyApplication2 event:" + myEvent.getContext());
}
}
三、事件通知
@Service
public class MyListenerService {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void register(MyEvent event){
applicationEventPublisher.publishEvent(event);
}
}