行为型-观察者模式

慈云数据 1年前 (2024-03-15) 技术支持 52 0

文章目录

  • 基本概念
    • 定义
    • 使用场景
    • 代码实现
    • 延伸阅读
      • 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);
            }
        }
        
微信扫一扫加客服

微信扫一扫加客服