• java(面向对象)的23种设计模式(11)——观察者模式


    一、定义

    观察者模式:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    换种说法,定义两种对象,观察者和目标对象,多个观察者同时监听一个目标对象,一旦这个目标对象发生改变,这些观察者都能立马知道并作出反应。
    观察者模式又叫发布-订阅模式、模型-视图模式,它是对象行为型模式。
    举个栗子:
    最近世界杯,假设内马尔是目标对象,观众是观察者,内马尔连过五人射门成功,观众热烈鼓掌;内马尔被恶意犯规,观众发出嘘~声。

    二、结构

    如图所示:抽象观察者,抽象目标对象,具体观察者,具体目标对象。
    在这里插入图片描述

    三、代码实现

    抽象目标:

    /**
     * 目标对象——被观察者
     */
    public interface MyTestSubject<T> {
    
        void setState(Integer state);
    
        //加入观察者
         void register(T t);
        //移除观察者
         void remove(T t);
        //通知观察者
         void notifyOthers();
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    抽象观察者:

    /**
     * 抽象观察者
     */
    public interface MyTestObserver {
        //事件发生
        void update();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    具体目标对象:

    /**
     * 具体目标对象
     */
    public class StateSubject implements MyTestSubject<MyTestObserver> {
    
        private List<MyTestObserver> observers = new ArrayList<>();
    
        Integer state;
    
        public Integer getState() {
            return state;
        }
    
        @Override
        public void setState(Integer state) {
            this.state = state;
            notifyOthers();
        }
    
        @Override
        public void register(MyTestObserver iObserver) {
            observers.add(iObserver);
        }
    
        @Override
        public void remove(MyTestObserver iObserver) {
            observers.remove(iObserver);
        }
    
        public void notifyOthers() {
            for (MyTestObserver iObserver : observers) {
                iObserver.update();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    具体观察者:

    **
     * 具体观察者
     */
    public class StateObserver implements MyTestObserver {
    
        @Override
        public void update() {
            System.out.println("状态改变");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试代码:

      public static void main(String[] args) {
            MyTestObserver myTestObserver = new StateObserver();
            MyTestSubject<MyTestObserver> myTestSubject = new StateSubject();
            //加入观察者队列
            myTestSubject.register(myTestObserver);
            //目标更改状态并通知
            myTestSubject.setState(11);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果如下:

    状态改变
    
    • 1

    四、应用

    1、jdk

    jdk中是提供了接口和抽象类来实现观察者功能的。包含两个类:java.util.Observable 和 java.util.Observer。前者是被观察者,后者是观察者。
    代码实现类似于上面自己定义的观察者逻辑,只是抽象的观察者和目标对象jdk给提供了。

    2、Spring

    Spring中的事件监听 机制,Spring中的ContextLoaderListener实现ServletContextListener,ServletContextListener又继承JDK的EventListener,实现事件监听。

    五、优缺点

    优点:
    1.观察者和被观察者都是松耦合(抽象耦合),符合依赖倒置原则。
    2.分离了表示层(观察者)和数据逻辑层(被观察者者),并且建立了一套触发机制,使得数据的变化可以响应到多个表示层。
    3.实现了一对多的通信机制,只有订阅的观察者可以接受通知。
    缺点:
    1.如果观察者过多,则事件通知会耗时较长。
    2.事件通知仅告知发生变化,未告知怎么发生了变化。
    3.观察者和被观察者可能存在循环依赖,可能造成循环调用,导致系统崩溃。

  • 相关阅读:
    机器学习笔记 - 深度学习中跳跃连接的直观解释
    Kubernetes云原生实战03 搭建高可用负载均衡器(Keepalived 和 HAproxy)
    STM32 4位数码管和74HC595
    【Vue 基础知识】控制元素显示隐藏的方法和区别
    「Android」孙正义|窥探OKHttp+Gson
    如何使用BI平台构建实时数据报告?-以HK-Omniscope为例
    NodeJs-http模块
    【Unity】AssetBundle加载与卸载
    7-2 友元类Cvector 武汉理工大学
    ActiveMQ 笔记(十)Linux部署:单机与集群部署流程
  • 原文地址:https://blog.csdn.net/liwangcuihua/article/details/128119052