行为型-观察者模式

文章目录

基本概念

定义

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。

观察者模式包含以下几个核心角色:

主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。

观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。

具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。

具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。

观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。

使用场景

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。通过这种事件触发的机制,将观察者和被观察者进行解耦。

注意事项:

1、JAVA 中已经有了对观察者模式的支持类。(Java中EventObject、EventListener)

2、避免循环引用。

3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

代码实现

主题接口

java 复制代码
/**
 * 抽象主题(抽象被观察者角色)
 */
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);
        }
    }

}

观察者接口

java 复制代码
/**
 * 观察者
 */
public interface Observer {

    void recvMsg(String content);
}

具体被观察者

java 复制代码
@Data
public class ConcreteSubject implements Subject<Observer> {

    private String msg;

    /**
     * 发送通知
     */
    public void sendMsg(){
        System.out.println("ConcreteSubject send msg: " + this.msg);
        notifyAllObserver(msg);
    }
}

具体观察者

java 复制代码
public class ConcreteObserver implements Observer {
    @Override
    public void recvMsg(String content) {
        System.out.println("ConcreteObserver recv msg:" + content);
    }
}

测试

java 复制代码
public class ObserverTest {

    public static void main(String[] args) {
        ConcreteSubject concreteSubject = new ConcreteSubject();
        concreteSubject.setMsg("important msg");
        concreteSubject.addObserver(new ConcreteObserver());
        concreteSubject.sendMsg();
    }
}

延伸阅读

java监听机制

一、创建事件对象

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;
    }
}

二、创建监听器

java 复制代码
public interface MusicListener extends EventListener {

    void play(MusicEvent musicEvent);
}

CloseMusicListener实现

java 复制代码
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实现

java 复制代码
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!");
        }
    }
}

三、定义事件源,管理监听器

java 复制代码
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);
        }
    }
}

四、测试

java 复制代码
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

java 复制代码
@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

java 复制代码
public class MyApplication1 implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent myEvent) {
        System.out.println("MyApplication1 event:" + myEvent.getContext());
    }
}

MyApplication2

java 复制代码
public class MyApplication2 implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent myEvent) {
        System.out.println("MyApplication2 event:" + myEvent.getContext());
    }
}

三、事件通知

java 复制代码
@Service
public class MyListenerService {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public void register(MyEvent event){
        applicationEventPublisher.publishEvent(event);
    }
}
相关推荐
hxj..13 小时前
【设计模式】观察者模式
java·观察者模式·设计模式
潘多编程15 小时前
Spring Boot观察者模式实战
spring boot·后端·观察者模式
九鼎科技-Leo1 天前
在 C# 中,如何实现观察者模式?
观察者模式·c#·.net
老攀呀3 天前
观察者模式(Observer Pattern)
观察者模式
倚-天-照-海5 天前
Java设计模式之观察者模式
java·观察者模式·设计模式
郑..方..醒8 天前
设计模式-观察者模式(代码实现、源码级别应用、使用场景)
观察者模式·设计模式
CV猿码人8 天前
设计模式-观察者模式
观察者模式·设计模式
前端拾光者8 天前
前端开发设计模式——观察者模式
观察者模式·设计模式
徒步僧13 天前
Java设计模式—观察者模式详解
java·观察者模式·设计模式
morning_judger14 天前
【设计模式系列】观察者模式
java·观察者模式·设计模式