详解设计模式:观察者模式

news2024/9/30 21:22:11

观察者模式(Observer Pattern)也被称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式,是在 GoF 23 种设计模式中定义了的行为型模式。

观察者模式 定义了一对多的关系,让多个观察者对象同时监听某一个主体对象,这个主体对象发生变化时就会通知所有的观察者对象,使得他们能够自己更新自己。

本片文章内容包括:关于观察者模式、观察者模式 Demo(伪代码)


文章目录

    • 一、关于观察者模式
        • 1、关于观察者模式
        • 2、关于观察者模式构成
        • 3、关于观察者模式XML
        • 4、观察者模式解决的问题
        • 5、观察者模式的优点和缺点
    • 二、观察者模式 Demo(伪代码)
        • 1、伪代码 Demo 实现
        • 2、Demo 测试


一、关于观察者模式

1、关于观察者模式

观察者模式(Observer Pattern)也被称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式,是在 GoF 23 种设计模式中定义了的行为型模式。

观察者模式 定义了一对多的关系,让多个观察者对象同时监听某一个主体对象,这个主体对象发生变化时就会通知所有的观察者对象,使得他们能够自己更新自己。

观察者模式的特点:

  1. 被观察者不知道具体的观察者是谁,只知道自己被观察了,并且在合适的时机进行广播,让感兴趣的观察者知道发生了什么事情;

  2. 观察者依赖于被观察者,被观察者不依赖于观察者,是单向关系,耦合程度不高。没有被观察者,观察者无法工作;没有观察者,被观察者该干啥干啥,因为被观察者本来就不清楚谁观察他,发广播是被观察的个人行为;

  3. 通常被观察者出现行为上的变化,需要观察者做出反馈。显然一般情况下观察者并不知道被观察者啥时候会有变化,因此该反馈是一种被动反馈,实现的是一种回调机制。

2、关于观察者模式构成

策略模式主要由 4 种角色构成:

  • 目标(Subject):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供了一系列方法来增加和删除观察者对象,同时它定义了通知方法 notify()。目标类可以是接口,也可以是抽象类或具体类。
  • 具体目标(ConcreteSubject):具体目标是目标类的子类,它通常包含有经常发生改变的数据,当它的状态发生改变时它向各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法。如果无须扩展目标类,具体目标类可以省略。
  • 观察者(Observer):观察者将对观察目标的改变做出反映,观察者一般定义为接口,该接口声明了更新数据的方法 update(),因此又称为抽象观察者。
  • 具体观察者(ConcreteObserver):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者 Observer 中定义的 update() 方法。通常在实现时可以调用具体目标类的 attach() 方法将自己添加到目标类的集合中或者通过 detach() 方法将自己从目标类的集合中删除。

3、关于观察者模式XML

观察者模式

4、观察者模式解决的问题

  • 定义对象之间的一对多依赖关系而不使对象紧密耦合。
  • 确保当一个对象改变状态时,自动更新开放数量的从属对象。
  • 一个对象应该可以通知开放式数量的其他对象

5、观察者模式的优点和缺点

# 观察者模式的优点

  • 观察者与被观察者抽象耦合,容易扩展;
  • 建立了一套触发机制。

# 观察者模式的缺点:

  • 循环依赖会导致系统崩溃;
  • 观察者太多会浪费时间。

二、观察者模式 Demo(伪代码)

1、伪代码 Demo 实现

# Subject 目标

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

public abstract class Subject {
    /**
     * 定义一个观察者集合用于存储所有观察者对象
     */
    protected List<Observer> observers = new ArrayList<Observer>();

    /**
     * 注册方法,用于向观察者集合中增加一个观察者
     * @param observer Observer
     */
    public void attachObserver(Observer observer) {
        observers.add(observer);
    }

    /**
     * 注销方法,用于在观察者集合中删除一个观察者
     * @param observer Observer
     */
    public void detachObserver(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 声明抽象通知方法
     */
    public abstract void notifyObserver();
}

# ConcreteSubject 具体目标

public class ConcreteSubject extends Subject {

    /**
     * 实现通知方法
     */
    @Override
    public void notifyObserver() {
        //遍历观察者集合,调用每一个观察者的响应方法
        for(Observer obs:observers) {
            obs.update();
        }
    }
}

# Observer 观察者

public interface Observer {

    /**
     * 声明响应方法
     */
    public void update();
}

# ConcreteObserver 具体观察者

public class ConcreteObserverA implements Observer {
    /**
     * 实现响应方法
     */
    @Override
    public void update() {
        //具体响应代码
        System.out.println("ConcreteObserverA 相应");
    }
}
public class ConcreteObserverB implements Observer {
    /**
     * 实现响应方法
     */
    @Override
    public void update() {
        //具体响应代码
        System.out.println("ConcreteObserverB 相应");
    }
}

2、Demo 测试

public class Client {

    public static void main(String[] args) {

        Subject subject = new ConcreteSubject();

        subject.attachObserver(new ConcreteObserverA());
        subject.attachObserver(new ConcreteObserverB());

        subject.notifyObserver();
        
    }

}

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

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

相关文章

牛客网最新Java面试通关八股文手册,花点耐心每天刷上10道题,挑战一下年薪50W!

明年金三银四不少人已经蓄势待发&#xff0c;信心满满地准备投递简历&#xff0c;到处面试&#xff0c;在不同的 Offer 之中择优而栖。 与此同时&#xff0c;也有人会悔恨自己这半年进步不大&#xff0c;每天噼里啪啦敲代码&#xff0c;但面对那些不能再熟悉的 Java 面试题时&…

H2N-Val-Pro-Pro-COOH,58872-39-2

H-Val-Pro-Pro-OH&#xff0c;是牛奶来源的脯氨酸肽衍生物&#xff0c;是血管紧张素 I 转化酶 (ACE) 的抑制剂&#xff0c;其IC50 为 9 μM。H-Val-Pro-Pro-OH, a milk-derived proline peptides derivative, is an inhibitor of Angiotensin I converting enzyme (ACE), with …

C++手敲基于梯度图和像素数量数组的OTSU阈值分割

一、OTSU算法原理 ➢OTSU法&#xff08;最大类间方差法&#xff0c;有时也称之为大津算法&#xff09; ➢ 使用聚类的思想&#xff0c;把图像的灰度数按灰度级分成2个部分&#xff0c; 使得两个部分之间的灰度值差异最大&#xff0c;每个部分之间的灰 度差异最小 ➢ 通过方…

数学建模-2022年亚太赛C题(含思路过程和代码)

目录 一、题目以及大概的思路 二、数据预处理 三、预测模型 四、全球变暖的相关性分析 五、赛后总结 一、题目以及大概的思路 先对数据进行无量纲化处理&#xff0c;根据所给不确定度与数据&#xff0c;计算出相对不确定度&#xff0c;并将其异常点剔除&#xff0c;通常情况…

[附源码]计算机毕业设计病房管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Cisco ASA防火墙——远程控制与多安全区域

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.远程管理ASA 1.配置Telnet接入 2.配置SSH接入 3.配置ASDM接…

Java数据结构与Java算法学习Day02---算法排序

目录 一、简单排序 1.1Comparable接口介绍 11 1.2冒泡排序 12、13、14 1.3选择排序 15、16、17 1.4插入排序 18、19、20 二、高级排序 2.1希尔排序 21、22、23 2.2归并排序 24 2.2.1递归 24 2.2.2归并排序 25 2.3快速排序 32 2.3.1快速排序的原理 32 2.3.2快速排序…

这可能是我见过最可爱的乒乓女孩了!

3D角色艺术家Carlos Sanz曾在U-tab学习动画&#xff0c;在CICE学习角色创作&#xff0c;现在正致力于创作她的作品集并成为3D动画行业的一员&#xff0c;本文是作者在ZBrush和Maya等软件中设计乒乓女孩角色造型的教程&#xff1a; 首先给大家做个自我介绍。我叫Carlos Sanz&am…

[附源码]计算机毕业设计springboot网上电影购票系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

(阅读笔记)急性卒中CT灌注分析在临床中的实际问题

&#xff08;阅读笔记&#xff09;急性卒中CT灌注分析在临床中的实际问题IntroductionUnderstanding the basics of CTP acquisition and processingCTP thresholds and quantificationPitfalls of perfusion imagingTechnical pitfallsPatient motionContrast bolusRadiationC…

CMMI和SPCA是一样的吗?有什么区别

CMMI资质相信有很多企业都了解了&#xff0c;对于SPCA可能有些企业是比较陌生的&#xff0c;不太了解什么是SPCA&#xff0c;简单来说可以理解为CMMI是国外的资质&#xff0c;而SPCA可以理解为国内的&#xff0c;那现在就跟随同邦信息科技的小编一起来看看具体的区别是哪些吧 C…

进程以及线程

目录 &#x1f43c;今日良言:希望是生命的源泉&#xff0c;失去它生命就会枯萎。 &#x1f42f;一、进程 &#x1f415;1.概念 &#x1f415;2.PCB &#x1f415;3.进程调度 &#x1f42d;二、线程 &#x1f411;1.概念 &#x1f407;三、进程和线程的联系和区别 &…

Qt实现抽奖程序

一、简介 该程序命名为Lucky&#xff0c;实现的功能如下&#xff1a; 1. 加载抽奖人员名单&#xff0c;并保存加载路径&#xff1b; 2. 单击左键或者点击ctrls开始抽奖&#xff0c;并滚动显示人员名单&#xff0c;显示的人员名单格式为 部门-姓名。 3. 单击左键或者点击ctrls…

了解并应用数字隔离器的安全限值

介绍 电流隔离在工业和汽车系统中很常见&#xff0c;作为防止高电压或抵消接地电位差的一种手段。设计人员传统上使用光耦合器进行隔离&#xff0c;但在过去几年中&#xff0c;使用电容和磁隔离的数字隔离器变得越来越流行。对于任何此类隔离器&#xff0c;了解其安全限值的重…

关于如何找环形链表的入环点

目录一、判断一个链表是否有环二、找到链表入环的第一个节点一、判断一个链表是否有环 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的…

菇多糖-聚乙二醇-大环配体NOTA,大环配体NOTA-PEG-香菇多糖

菇多糖-聚乙二醇-大环配体NOTA&#xff0c;大环配体NOTA-PEG-香菇多糖 中文名称&#xff1a;香菇多糖-大环配体NOTA 英文名称&#xff1a;Lentinan-NOTA 别称&#xff1a;NOTA修饰香菇多糖&#xff0c;NOTA-香菇多糖 PEG接枝修饰香菇多糖 Lentinan-PEG-NOTA 香菇多糖-聚乙…

设置Excel表格“只读模式”的两种方法

Excel表格的“只读模式”可以帮助我们防止意外更改表格&#xff0c;根据不同需求&#xff0c;表格可以设置“有密码”和“无密码”的两种“只读模式”&#xff0c;下面来说说具体设置方法。 一、无密码“只读模式” 如果主要是想防止自己意外修改了表格&#xff0c;可以设置没…

Jenkins拉分支代码 + tortoiseGit删除分支

日常部署测试代码都使用Jenkins代码手工上传代码&#xff0c;主要减减减减工作量&#xff0c;提高工作效率&#xff1b; 一、安装Git、git-parameter插件及配置方法&#xff0c;安装方法忽略一万字&#xff0c;解决不了绕道度娘问问 二、创建项目&#xff0c;设置参数 This pr…

[操作系统笔记]基本分页存储管理

内容系听课复习所做笔记&#xff0c;图例多来自课程截图 基本分页存储管理 两次访存&#xff0c;第一次查页表&#xff0c;第二次访问目标内存单元 将内存空间分为一个个大小相等的分区&#xff08;比如每个分区4KB&#xff09;&#xff0c;每个分区就是一个“页框”&#xff0…

[附源码]计算机毕业设计springboot物业管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…