文章目录
- 基本概念
- 定义
- 使用场景
- 代码实现
- 延伸阅读
- java监听机制
- spring监听机制
基本概念
定义
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
(图片来源网络,侵删)观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。
观察者模式包含以下几个核心角色:
(图片来源网络,侵删)主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。
具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。
使用场景
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。通过这种事件触发的机制,将观察者和被观察者进行解耦。
注意事项:
1、JAVA 中已经有了对观察者模式的支持类。(Java中EventObject、EventListener)
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
代码实现
主题接口
/** * 抽象主题(抽象被观察者角色) */ public interface Subject { /** * 所有抽象观察者角色的集合 */ List 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 { 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 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 { @Override public void onApplicationEvent(MyEvent myEvent) { System.out.println("MyApplication1 event:" + myEvent.getContext()); } }
MyApplication2
public class MyApplication2 implements ApplicationListener { @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); } }