JAVA设计模式之观察者模式( 通俗易懂的代码讲解 )

news2024/11/27 18:39:13

     简述:Java的观察者模式是一种设计模式,它定义了一种对象间的一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能够得到收到消息通知。在这种模式中,被观察者维护了一个观察者列表,并提供了添加删除通知观察者的方法。

目录

一、什么是观察者模式

二、观察者模式使用场景

三、观察者与被观察者直观的关系图

四、完整代码示例,方便理解

1、首先定义被观察者接口类Observable:

2、观察者接口实现类:

3、再定义观察者接口类Observer:

4、再定义观察者接口实现类MyObserver:

5、主播开播发送通知消息演示:


一、什么是观察者模式

     观察者先订阅被观察者对象,当被观察者行为发生改变时,观察者就能及时收到消息通知。

二、观察者模式使用场景

    一个对象需要将自己的状态改变通知给其它多个对象,一个对象与它的多个依赖对象需要解耦,以便能对其修改,但不会对其它对象产生影响。

三、观察者与被观察者直观的关系图

     举例:张三(观察者1)、李四(观察者2)、张三(观察者1)在抖音上关注了某个美女主播,当美女主播开播时,他们的粉丝能收到开播的消息推送。在直播间里的这些观察者,可以观察到美女行为变化(如:跳舞、唱歌表演)。

四、完整代码示例,方便理解

以下是一个Java观察者模式的示例代码:

1、首先定义被观察者接口类Observable:

/**
 * 被观察者
 */
public interface Observable {

    void addObserver(Observer observer);

    void removeObserver(Observer observer);

    void sendMessage(String message);
}

2、观察者接口实现类:

内含有:观察者列表,并提供了添加、删除和通知观察者的实现方法

/**
 * 被观察者实现类
 */
public class MyObservable implements Observable {

    private static volatile MyObservable instance = null;
    
    private MyObservable() {

    }
    
    public static MyObservable getInstance() {
        if (instance == null) {
            synchronized (MyObserver.class) {
                if (instance == null) {
                    instance = new MyObservable();
                }
            }
        }
        return instance;
    }
    
    //维护的观察者列表
    private List<Observer> mObservers = new ArrayList<>();


    @Override
    public void addObserver(Observer observer) {
        mObservers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        mObservers.remove(observer);
    }

    @Override
    public void sendMessage(String message) {
        notifyObserver(message);
    }

    /**
     * 通知所有观察着
     * 
     * @param message
     */
    private void notifyObserver(String message) {
        for (Observer observer : mObservers) {
            observer.receiveMessage(message);
        }
    }
}

3、再定义观察者接口类Observer:

/**
 * 观察者
 */
public interface Observer {
    
    void receiveMessage(String message);
    
}

4、再定义观察者接口实现类MyObserver:

/**
 * 观察则实现类
 */
public class MyObserver implements Observer {
    private String key;
    private ObserverListener mObserverListener;

    public MyObserver(String key, ObserverListener observerListener) {
        this.key = key;
        this.mObserverListener = observerListener;
    }

    @Override
    public void receiveMessage(String message) {
        if (mObserverListener != null) {
            System.out.println( key + "---------接收到消息:《" + message+"》");
            mObserverListener.receive(message);
        }
    }

    public interface ObserverListener {
        void receive(String message);
    }

}

5、主播开播发送通知消息演示:

/**
 * 演示代码
 */
public class Main {

    public static void main(String[] args) {
        //粉丝1订阅
        MyObserver observer1=new MyObserver("粉丝-老林", message -> {
              //这里进行消息处理
        });
        //粉丝2订阅
        MyObserver observer2=new MyObserver("粉丝-老王", message -> {
               //这里进行消息处理
        });

        //加入观察者列表
        MyObservable.getInstance().addObserver(observer1);
        MyObservable.getInstance().addObserver(observer2);

        //通知所有订阅的观察者
        MyObservable.getInstance().sendMessage("大家好,菲儿已开播了,赶快来我直播间吧!");
    }
}


                                       各位看官,麻烦点个赞,感谢 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入浅出 Compose Compiler(1) Kotlin Compiler KCP

前言 Compose 的语法简洁、代码效率非常高&#xff0c;这主要得益于 Compose Compiler 的一系列编译期魔法&#xff0c;帮开发者生成了很多样板代码。但编译期插桩也阻碍了我们对于 Compose 运行原理的认知&#xff0c;想要真正读懂 Compose 就必须先了解它的 Compiler。本系列…

前端系列11集-ES6 知识总结

ES Module 优点 静态分析 浏览器和 Node 都支持 浏览器的新 API 能用模块格式提供 不再需要对象作为命名空间 export 用于规定模块的对外接口 输出的接口与其对应的值是动态绑定关系可以取到模块内部实时的值 import 用于输入其他模块提供的功能 具有提升效果&#xff0c;会提升…

刷题4.28

1、 开闭原则软件实体&#xff08;模块&#xff0c;类&#xff0c;方法等&#xff09;应该对扩展开放&#xff0c;对修改关闭&#xff0c;即在设计一个软件系统模块&#xff08;类&#xff0c;方法&#xff09;的时候&#xff0c;应该可以在不修改原有的模块&#xff08;修改关…

服务注册与发现-Consul(Linux)

本文要有docker支持&#xff0c;docker的安装使用Docker 在Linux-CentOS上的安装使用_XiaoGuaiSs的博客-CSDN博客如果提示 [Warning] IPv4 forwarding is disabled. Networking will not work.然后将项目拷贝至linux 的project目录下&#xff08;随意&#xff09;。生成项目镜像…

Node第三方包 【Request】

文章目录 &#x1f31f;前言&#x1f31f;Request&#x1f31f;安装与使用&#x1f31f;流&#xff08;stream&#xff09;操作&#x1f31f;Form表单&#x1f31f;application/x-www-form-urlencoded (URL编码的Form)&#x1f31f;multipart/form-data (Multipart Form 上传) …

百度地图采集经纬度坐标数据定位的javascript实战开发(地理坐标拾取系统、地址定位点选插件、实时定位、数据导入、地理编码、位置纠偏)

坐标采集 前言1.百度地图地理坐标拾取系统2.位置选择插件百度地图经纬度选择插件默认参数配置 3.数据导入4.地理编码爬取百度webAPI返回参数前端封装转换函数 5.手机GPS定位GPS定位 6.位置纠偏html容器经纬度纠偏 前言 在百度地图的标注开发中&#xff0c;最为关键的操作就是经…

华硕主板来电开机自启

重启电脑&#xff0c;开机按del或者F2进入bios 按F10保存确认即可

浏览器跨站点通信(两个IP不同网站通信)

需求场景&#xff1a;OA系统会通过接口调用的方式将ERP系统的待办信息获取并显示在OA系统中。登录OA系统后&#xff0c;在OA系统中点击ERP系统的待办&#xff0c;会自动打开ERP系统业务处理页面&#xff0c;当ERP系统对应业务处理完毕&#xff0c;需要在OA系统中刷新待办记录&a…

【环境配置】解决No module named ‘librosa‘

执行以下命令下载 pip install librosa我这里遇到了报错&#xff1a; Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-build-tools/ 相关解决方案请参考&#xff1a; 【环境配置…

Python渗透测试编程基础——线程、进程与协程

目录 一、进程与线程的概念 1.进程 2.线程 3.进程和线程的关系 4.任务执行方式 二、Python中的Threading模块 1.线程模块介绍 2.Threading介绍 &#xff08;1&#xff09;方法和属性 &#xff08;2&#xff09;类方法 三、线程简单编写 1.流程 2.创建线程 &#x…

云原生技术在云计算中的应用探讨

第一章&#xff1a;云原生技术的概念与发展 云原生技术是一种针对云计算环境设计的应用程序开发和部署方法&#xff0c;主要目标是提高应用程序的可伸缩性、可移植性、高可用性和自动化管理等方面的特性。这种技术是近年来在云计算领域兴起的一个新的开发模式&#xff0c;它主要…

大模型“涌现”的思维链,究竟是一种什么能力?

听说最近AI大厂的开发人员和高校的NLP研究人员&#xff0c;都在琢磨&#xff0c;怎么让大模型“涌现”。那画面莫名就让我想到了程序员给服务器上香来保佑不宕机&#xff0c;都有种求诸于天的玄学。 所谓“涌现”,在大模型领域指的是当模型突破某个规模时&#xff0c;性能显著提…

商城管理系统的数据表从属关系+navicat建表操作+数据库文件转储并入代码操作

1&#xff0c;商城管理系统的数据表从属关系 在商城管理系统中&#xff0c;我们会面临属性分组的问题&#xff0c;商品表与分类表需要建立链接&#xff1b; 在控制类中我们将分类表中属性类传过来&#xff0c;与商品值params建立链接 public R list(RequestParam Map<Strin…

基于matlab使用波束成形对点对点 MIMO-OFDM 系统进行建模

一、前言 此示例展示了如何使用波束成形对点对点 MIMO-OFDM 系统进行建模。最近的无线标准&#xff08;如 802.11x 系列&#xff09;采用了多输入多输出 &#xff08;MIMO&#xff09; 和正交频分复用 &#xff08;OFDM&#xff09; 技术的组合&#xff0c;以提供更高的数据速率…

万字长文 - Nature 综述系列 - 给生物学家的机器学习指南 2 (传统机器学习方法如何选择)...

万字长文 - Nature 综述系列 - 给生物学家的机器学习指南 1 传统的机器学习 我们现在讨论几种关键的机器学习方法的优势和劣势。表1显示了不同机器学习方法的比较。我们首先讨论不基于神经网络的方法&#xff0c;有时被称为“传统机器学习”。 图3显示了一些传统的机器学习方法…

【算法基础】常见排序算法(持续更新中)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有…

【KVM虚拟化】· 图形化KVM安装linux

目录 &#x1f341;虚拟化技术 &#x1f342;KVM的整体结构 &#x1f342;KVM 的功能列表 &#x1f342;KVM 工具集合 &#x1f341;安装kvm虚拟化功能 &#x1f341;创建虚拟机 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;KVM虚拟化…

FreeRTOS 信号量(二) ------ 计数型信号量

文章目录 一、计数型信号量1. 计数型信号量简介2. 创建计数型信号量①函数 xSemaphoreCreateCounting()②函数 xSemaphoreCreateCountingStatic() 3. 计数型信号量创建过程分析4. 释放和获取计数信号量 二、计数型信号量操作实验 一、计数型信号量 1. 计数型信号量简介 有些资…

数据结构与算法(小议递归)

文章目录 前言一、递归是什么&#xff1f;二、在什么时候适用递归1.测试一下 总结 前言 递归是一种常用的算法设计&#xff0c;递归就是一种循环推理。简单来说就是调用原算法本身的算法。 这里主要探讨递归的使用&#xff0c; 一、递归是什么&#xff1f; 用一个简单的例子来…

嵌入式代码查看分析利器---Understand

平时在开发嵌入式程序的时候大多数使用的都是keil软件&#xff0c;一般小的工程使用keil没感觉到有什么问题&#xff0c;但是当工程比较大的时候&#xff0c;比如移植了FreeRTOS系统或者LWIP网络系统时&#xff0c;代码全部编译一次就要花费很长世间&#xff0c;特别是开启了点…