Java设计模式之一:观察者模式

目录

一、什么是观察者模式

二、如何使用观察者模式

三、观察者模式的优势和使用场景


 

一、什么是观察者模式

观察者模式是一种常见的设计模式,用于在对象之间建立一对多的依赖关系。在该模式中,一个主题(被观察者)维护了一个观察者列表,并在自身状态发生变化时通知所有观察者进行相应的更新。

观察者模式的核心概念包括以下几个角色:

  1. 主题(Subject):也称为被观察者或发布者,它维护了一个观察者列表,并提供方法用于注册、注销和通知观察者。

  2. 观察者(Observer):也称为订阅者或监听器,它定义了一个接口或抽象类,包含了观察者所需实现的方法,通常包括更新方法,在主题状态改变时被调用。

  3. 具体主题(Concrete Subject):实现主题接口或抽象类,具体主题维护自身状态,并在状态变化时通知观察者。

  4. 具体观察者(Concrete Observer):实现观察者接口或抽象类的具体类,它负责接收主题的通知并执行相应的操作。

观察者模式的优点在于解耦了主题和观察者之间的依赖关系,使得主题和观察者可以独立变化。当主题的状态发生改变时,所有观察者将被通知,从而实现了一种松耦合的方式来实现对象间的交互。

观察者模式广泛应用于许多场景,如事件处理、GUI开发、消息传递系统等。它提供了一种灵活的机制,使得对象之间能够及时响应和相互协作,同时也提高了代码的可维护性和可扩展性。

 

二、如何使用观察者模式

观察者模式是一种行为型设计模式,用于构建对象之间的一对多依赖关系。当一个对象(称为主题)的状态发生变化时,它会自动通知其所有依赖对象(称为观察者),以便它们可以做出相应的更新。

以下是一个使用Java实现观察者模式的简单示例代码:

首先,我们定义主题接口 Subject,其中包含了注册、注销和通知观察者的方法:

public interface Subject {
    void registerObserver(Observer observer);
    void unregisterObserver(Observer observer);
    void notifyObservers();
}

然后,我们定义观察者接口 Observer,其中包含了接收主题通知并进行相应操作的方法:

public interface Observer {
    void update();
}

接下来,我们实现具体的主题类 ConcreteSubject

import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void unregisterObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

最后,我们实现具体的观察者类 ConcreteObserver

public class ConcreteObserver implements Observer {
    private int observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject) {
        this.subject = subject;
        this.subject.registerObserver(this);
    }

    @Override
    public void update() {
        observerState = subject.getState();
        System.out.println("Observer state updated: " + observerState);
    }
}

现在,我们可以使用这些类来演示观察者模式的工作方式:

public class Main {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);

        subject.setState(10);
        // 输出:
        // Observer state updated: 10
        // Observer state updated: 10

        subject.setState(20);
        // 输出:
        // Observer state updated: 20
        // Observer state updated: 20

        subject.unregisterObserver(observer2);

        subject.setState(30);
        // 输出:
        // Observer state updated: 30
    }
}

在上述示例中,我们创建了一个具体主题对象 subject 和两个具体观察者对象 observer1 和 observer2。当主题的状态发生变化时,它会通知所有注册的观察者,并调用其 update() 方法进行更新。

观察者模式使得主题与观察者之间松散耦合,使系统更灵活和可扩展。当我们需要在对象之间建立一对多的依赖关系,并实现对象状态的同步更新时,观察者模式是一个常用且强大的设计模式。

 

三、观察者模式的优势和使用场景

观察者模式是一种行为型设计模式,用于在对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖对象都会自动收到通知并进行相应的更新。观察者模式具有以下优势和适用场景:

优势:

  1. 解耦:观察者模式将被观察者和观察者解耦,使它们可以独立地进行扩展和修改,而不会影响到彼此。
  2. 松散耦合:被观察者只需要知道观察者接口而不需要了解具体观察者的实现,从而降低了彼此之间的依赖程度,实现了松散耦合。
  3. 可重用性:观察者模式可增加新的观察者或被观察者,无需修改原有代码,提高了代码的可重用性。

使用场景:

  1. 当一个对象的改变需要同时通知其他多个对象,并且这些对象的更新操作可能不同步时,可以使用观察者模式。
  2. 当一个对象的状态变化需要引起其他相关对象的状态变化时,可以使用观察者模式来保持对象之间的一致性。
  3. 当系统中存在一个主体对象和多个观察者对象之间的动态关系,并且希望避免对象之间的紧耦合关系时,可以使用观察者模式。
  4. 当一个对象需要将自己的状态变化通知给一组观察者,同时这些观察者对象具有不同的行为和角色时,可以使用观察者模式。

总结来说,观察者模式适用于多个对象之间存在一对多的依赖关系,当一个对象的状态变化需要通知其他对象并进行相应处理时,观察者模式能够提供一种松散耦合的解决方案,增加系统的灵活性和可扩展性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣 93. 复原 IP 地址

题目来源&#xff1a;https://leetcode.cn/problems/restore-ip-addresses/description/ C题解&#xff1a;递归回溯法。 递归参数&#xff1a;因为不能重复分割&#xff0c;需要ind记录下一层递归分割的起始位置&#xff1b;还需要一个变量num&#xff0c;记录ip段的数量。递…

陪诊小程序系统|陪诊软件开发|陪诊系统功能和特点

随着医疗服务的逐步改善和完善&#xff0c;越来越多的人群开始走向医院就诊&#xff0c;而其中不少人往往需要有人陪同前往&#xff0c;这就导致了许多矛盾与问题的发生&#xff0c;比如长时间等待、找不到合适的陪诊人员等。因此为人们提供一种方便快捷的陪诊服务成为了一种新…

【实战】 二、React 与 Hook 应用:实现项目列表 —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表1.新建文件2.状态提升3.新建utils4.Custom Hook 学习内容来源&#xff1a;React React Hook TS 最佳实践-慕课网 相对原教程&#xff0c;我在学习开始时&#xff08;2023.0…

ClickHouse主键索引最佳实践

在本文中&#xff0c;我们将深入研究ClickHouse索引。我们将对此进行详细说明和讨论&#xff1a; ClickHouse的索引与传统的关系数据库有何不同ClickHouse是怎样构建和使用主键稀疏索引的ClickHouse索引的最佳实践 您可以选择在自己的机器上执行本文给出的所有Clickhouse SQL…

SQlite数据库

SQlite数据库 1.SQLite简介 轻量化&#xff0c;易用的嵌入式数据库&#xff0c;用于设备端的数据管理&#xff0c;可以理解成单点的数据库。传统服务器型数据库用于管理多端设备&#xff0c;更加复杂 SQLite是一个无服务器的数据库&#xff0c;是自包含的。这也称为嵌入式数…

2020年国赛高教杯数学建模C题中小微企业的信贷决策解题全过程文档及程序

2020年国赛高教杯数学建模 C题 中小微企业的信贷决策 原题再现 在实际中&#xff0c;由于中小微企业规模相对较小&#xff0c;也缺少抵押资产&#xff0c;因此银行通常是依据信贷政策、企业的交易票据信息和上下游企业的影响力&#xff0c;向实力强、供求关系稳定的企业提供贷…

Win10电脑开机PIN码怎么取消?

有的用户稀里糊涂的设置了PIN码之后&#xff0c;在开机时发现多了个PIN码&#xff0c;但又不知道电脑PIN码是什么意思&#xff0c;也不清楚开机PIN码怎么取消。您可以通过阅读以下内容&#xff0c;以了解什么是PIN以及如何取消PIN码。 PIN码是一种快捷登录密码方式&#xff0c;…

lesson 12 Zigbee绑定通信

目录 Zigbee绑定通信 通信原理 实验过程 实现步骤 实验现象 实验分析 Zigbee绑定通信 通信原理 1、Zigbee一共有五种通信方式&#xff1a;单播、广播、组播、MAC、广播 2、绑定是Zigbee的一种基本通信方式&#xff0c;具体绑定通信又分为三种模式&#xff0c;模式大同…

java 计算网段范围 分析网段包含关系

目录 一、网段范围 二、思路说明 三、代码 1、将一个ip转为数字 2、转换子网掩码&#xff08;255.255.255.0 转为 24&#xff09; 3、根据 ip 与 掩码 计算最大值和最小值 4、测试 5、完整代码 四、难点讲解 1、转换子网掩码&#xff0c; 例&#xff1a;255.255.25…

数据总线学习

为啥要数据总线 使用服务化方式发布&#xff0c;业务端和中间件完全解耦合。一处生产&#xff0c;处处消费设计理念。提供用户可定制的托管化通用消费方案&#xff08;如同步mysql到缓存&#xff0c;同步mysql到es&#xff0c;消费mysql到大数据等托管服务&#xff09; 特性 …

RabbitMQ系列(18)--RabbitMQ基于插件实现延迟队列

1、前往RabbitMQ官网下载往RabbitMQ添加延迟消息的插件 RabbitMQ官网下载插件的网址&#xff1a;https://www.rabbitmq.com/community-plugins.html 2、下载rabbitmq_delayer_message_exchange插件&#xff08;注&#xff1a;RabbitMQ是什么版本的&#xff0c;下载的插件就得是…

【UE5 Cesium】12-Cesium for Unreal 去除左下角的icon

问题 在视口左下角的icon如何去除&#xff1f; 解决方法 打开“CesiumCreditSystemBP” 将“Credit Widget Class”一项中的“ScreenCredit”替换为“ScreenCreditWidget” 编译之后icon就不显示了。

2023年5月PETS5(WSK)考试经验分享

由于本人明年打算出国联培的缘故&#xff0c;CSC国家留学基金委需要申请人的语言成绩达到一定的要求 英语&#xff08;PETS5&#xff09;&#xff1a;笔试总分55分&#xff08;含&#xff09;以上&#xff0c;其中听力部分18分&#xff08;含&#xff09;以上&#xff0c;口试…

2023最新AI创作系统/ChatGPT商业运营版网站程序源码+支持GPT4+支持ai绘画(MJ)+实时语音识别输入+免费更新版本

2023最新AI创作系统/ChatGPT商业运营版网站程序源码支持ai绘画支持GPT4.0实时语音识别输入文章资讯发布功能用户会员套餐免费更新版本 一、AI创作系统二、系统介绍三、系统程序下载四、安装教程五、主要功能展示六、更新日志 一、AI创作系统 1、提问&#xff1a;程序已经支持G…

“生鲜蔬”APP的设计与实现

1.引言 在这个科技与网络齐头并进的时代&#xff0c;外卖服务正在飞速发展&#xff0c;人们对外卖APP系统功能需求越来越多&#xff0c;开发APP的人员对自己的要求也要越来越高&#xff0c;要从所做APP外卖系统所实现的功能和用户的需求来对系统进行设计&#xff0c;还需要与当…

2023年船舶、海洋与海事工程国际会议(NAOME 2023) | Ei Scopus双检索

会议简介 Brief Introduction 2023年船舶、海洋与海事工程国际会议(NAOME 2023) 会议时间&#xff1a;2023年10月20日-22日 召开地点&#xff1a;中国镇江 大会官网&#xff1a;NAOME 2023-2023 International Conference on Naval Architecture and Ocean & Marine Engine…

腾讯云对象存储联合DataBend云数仓打通数据湖和数据仓库

随着数字化进程不断深入&#xff0c;数据呈大规模、多样性的爆发式增长。为满足更多样、更复杂的业务数据处理分析的诉求&#xff0c;湖仓一体应运而生。在Gartner发布的《Hype Cycle for Data Management 2021》中&#xff0c;湖仓一体&#xff08;Lake house&#xff09;首次…

ModaHub魔搭社区:基于阿里云 ACK 搭建开源向量数据库 Milvus

目录 一、准备资源 二、集群创建&#xff1a; 本集群基于Terway网络构建 二、连接刚刚创建的ACK集群 三、部署Milvus数据库 四、优化Milvus配置 简介&#xff1a; 生成式 AI&#xff08;Generative AI&#xff09;引爆了向量数据库&#xff08;Vector Database&#xff0…

【链表OJ】删除链表中重复的结点

⭐️ 往期链表相关OJ &#x1f4ab;链接1&#xff1a;链表分割 &#x1f4ab;链接2&#xff1a;链表中倒数第k个结点(快慢指针问题) &#x1f4ab;链接3&#xff1a;leetcode 876.链表的中间结点(快慢指针问题) &#x1f4ab;链接4&#xff1a;leetcode 206.反转链表 &#x1…

【数据结构与算法】内排序算法比较(C\C++)

实践要求 1. 问题描述 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶&#xff0c;或大概执行时间&#xff0c;试通过随机的数据比较各算法的关键字比较次数和关键字移动次数&#xff0c;以取得直观感受。 2. 基本要求 对以下10种常用的内部排序算法进行比较…