• java设计模式-观察者模式


    java设计模式-观察者模式

    什么是观察者模式

    一句话,观察者模式(Observer Pattern)就是一种 “发布者-订阅者” 的模式。有时也被称为“模型-视图”模式、“源-监听者”模式等。在这种模式中,由一个目标对象来管理所有依赖与它的观察者对象,并且当这个目标对象自身发生改变时,会主动向它的观察者们发出通知。

    观察者模式类图

    比如你最近在追一个美剧《生活大爆炸》,假设著名在线视频网站某狐买下独家版权,在线更新与播放。于是你天天等啊等啊,等它的更新通知一来,你就去看那些最新的视频。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YvBRCUkK-1660629193287)(https://dn-simplecloud.shiyanlou.com/questions/uid810810-20220802-1659427435727)]

    观察者模式示例代码

    面的代码块中是全部的代码,实际操作中应当按注释创建相应的类再将方法写入对应的类中。

    // Subject 主题接口
    public interface Subject {
        public void registerObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyAllObservers();
    }
    
    // 观察者接口
    public interface Observer {
        public void update(Subject s);
    }
    
    // 视频网站某狐 实现 Subject 接口
    public class VideoSite implements Subject{
    
        // 观察者列表 以及 更新了的视频列表
        private ArrayList<Observer> userList;
        private ArrayList<String> videos;
    
        public VideoSite(){
            userList = new ArrayList<Observer>();
            videos = new ArrayList<String>();
        }
    
        @Override
        public void registerObserver(Observer o) {
            userList.add(o);
        }
    
        @Override
        public void removeObserver(Observer o) {
            userList.remove(o);
        }
    
        @Override
        public void notifyAllObservers() {
            for (Observer o: userList) {
                o.update(this);
            }
        }
    
        public void addVideos(String video) {
            this.videos.add(video);
            notifyAllObservers();
        }
    
        public ArrayList<String> getVideos() {
            return videos;
        }
    
        public String toString(){
            return videos.toString();
        }
    }
    
    // 实现观察者,即看视频的美剧迷们
    public class VideoFans implements Observer {
    
        private String name;
    
        public VideoFans(String name){
            this.name = name;
        }
        @Override
        public void update(Subject s) {
            System.out.println(this.name + ", new videos are available! ");
            // print video list
            System.out.println(s);
        }
    }
    
    //  测试一下
    public class Main {
    
        public static void main(String[] args) {
            VideoSite vs = new VideoSite();
            vs.registerObserver(new VideoFans("LiLei"));
            vs.registerObserver(new VideoFans("HanMeimei"));
            vs.registerObserver(new VideoFans("XiaoMing"));
    
            // add videos
            vs.addVideos("Video 1");
            //vs.addVideos("Video 2");
        }
    }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    运行结果为:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KxJzt6CQ-1660629193289)(https://doc.shiyanlou.com/userid46108labid878time1429498396393)]

    可能有同学会问,为什么打印出了[Video 1],我们来看类 VideoSite 中的 toString() 方法返回的是 ArrayList 的 videos 对象,当 notifyAllObservers() 方法中调用 update()方法,传递 this 参数的时候,相当于传递了 videos 的值。具体可以参考JAVA 中 toString 方法的作用

    观察者模式的应用

    前面已经说了,观察者模式也可以理解为 “源-监听者” 模式,这种应用就太多了。举个简单的例子就是各种 listener,比如当你有一个按键,你肯定要给这个按键添加监听事件(listener)来完成指定动作吧,这就是一种应用。

    参考链接

  • 相关阅读:
    OpenAI开发系列(二):大语言模型发展史及Transformer架构详解
    网页整体如何实现网页变灰效果
    Lua __metatable键
    你不知道的JavaScript性能测试 之 两个变量值交换
    Spring Boot 自动配置原理
    理想正方形(单调队列),22数(数位dp)
    如何将扫描的 PDF 转换为 Word
    asp核酸检测预登记系统源码
    高级管理学:大题
    vue3+pinia实现动态类名及动态颜色
  • 原文地址:https://blog.csdn.net/Deng872347348/article/details/126364784