第十八章行为性模式—观察者模式

news2024/12/25 14:11:27

文章目录

  • 观察者模式
    • 解决的问题
    • 结构
    • 实例
    • 存在的问题
    • 使用场景
  • JDK 提供的实现 - Observable
    • 示例

行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式:

  • 类行为模式:采用继承机制来在类间分派行为

  • 对象行为模式:采用组合或聚合在对象间分配行为

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型模式分为:

  • 模板方法模式
  • 策略模式
  • 命令模式
  • 职责链模式
  • 状态模式
  • 观察者模式
  • 中介者模式
  • 迭代器模式
  • 访问者模式
  • 备忘录模式
  • 解释器模式

以上 11 种行为型模式,除了模板方法模式解释器模式是类行为型模式,其他的全部属于对象行为型模式。

观察者模式

观察者模式:又被称为 发布 - 订阅(Publish / Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己

解决的问题

image-20230524155714641

张三是一个老板,由于效益不好,所以向王五,赵六,老八他们借钱,但是因为经营不善,导致公司倒闭,债主肯定是想要张三还钱,债主很相信张三的人品,知道张三肯定会还钱,但是不知道什么时候还

  • 第一种方式,债主们天天主动去问张三有没有钱还,这样张三天天都要去回答这么多债主的询问,债主们也很忙,还需要天天去问张三
  • 第二种方式,债主们拿着张三欠钱的合同,当张三有钱了,就主动去告诉债主还钱了
  • 张三和债主之间这种一对多的关系

结构

  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

实例

微信公众号

在使用微信公众号时,大家都会有这样的体验,当你关注的公众号中有新内容更新的话,它就会推送给关注公众号的微信用户端。我们使用观察者模式来模拟这样的场景,微信用户就是观察者,微信公众号是被观察者也就是主题对象,有多个的微信用户关注了程序猿这个公众号。

抽象观察者

public interface Observer {
    void update(String message);
}

具体观察者:微信用户,实现了更新的方法

public class WeiXinUser implements Observer{
    private String name;

    public WeiXinUser(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name+"--"+message);
    }
}

抽象被观察者

public interface Subject {
    // 添加订阅者(添加观察者对象)
    void attach(Observer observer);
    // 删除订阅者
    void detach(Observer observer);
    // 通知订阅者更新消息
    void notify(String message);

}

具体被观察者:微信公众号,里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法

public class SubscriptionSubject implements Subject{
    //定义一个集合,用来存储多个观察者对象
    private List<Observer> weiXinUserList = new ArrayList<>();
    @Override
    //订阅
    public void attach(Observer observer) {
        weiXinUserList.add(observer);
    }

    @Override
    //取消订阅
    public void detach(Observer observer) {
        weiXinUserList.remove(observer);
    }

    @Override
    //公众号发表内容
    public void notify(String message) {
        for (Observer observer: weiXinUserList) {
            // 调用观察者对象中的update方法
             observer.update(message);
        }
    }
}

测试

public class Client {
    public static void main(String[] args) {
        //1创建公众号对象 主题类对象(被观察者)
        SubscriptionSubject subject = new SubscriptionSubject();
        //2订阅公众号
        subject.attach(new WeiXinUser("孙悟空"));
        subject.attach(new WeiXinUser("猪悟能"));
        subject.attach(new WeiXinUser("沙悟净"));
        //3公众号更新,发出消息给订阅者(观察者对象)
        subject.notify("公众号更新啦");
    }
}

存在的问题

优点:

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。

  • 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】。

缺点:

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时。
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃。

使用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时。

JDK 提供的实现 - Observable

该类在 JDK9 中被弃用

在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

**Observable 类:**抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象。

  • void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。

  • void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。

  • void setChange() 方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为 true 时,notifyObservers() 才会通知观察者。

**Observer 接口:**抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 update 方法,进行相应的工作。

示例

警察抓小偷

警察抓小偷也可以使用观察者模式来实现,警察是观察者,小偷是被观察者。

被观察者对象

@Data
public class Thief extends Observable {
    private String name;
    public Thief(String name) {
        this.name = name;
    }
    public void steal(){
        System.out.println("小偷:我偷东西了,有没有人来抓我!!!");
        super.setChanged(); // changed  = true
        // 当它为 true 时,notifyObservers() 才会通知观察者。
        super.notifyObservers();
    }
}

观察者对象

public class Policemen implements Observer {
    private String name;

    public Policemen(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("警察:" + ((Thief) o).getName() + ",我已经盯你很久了!!!");
    }
}

测试

public class Client {
    public static void main(String[] args) {
        //创建小偷对象
        Thief thief = new Thief("小偷");
        //创建警察对象
        Policemen policemen = new Policemen("lsc");
        //让警察盯着小偷
        thief.addObserver(policemen);
        //小偷投东西
        thief.steal();
    }
}
小偷:我偷东西了,有没有人来抓我!!!
警察:小偷,我已经盯你很久了!!!

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

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

相关文章

WMI系列--WMI订阅事件

前边对于WMI的基础内容进行简单的总结和整理&#xff0c;结下来的这篇内容主要针对WMI的永久订阅事件展开详细的阐述。 WMI事件订阅机制 WMI事件分为两类&#xff0c;分别是本地事件订阅和永久性事件订阅。 所谓本地事件是指运行在本地上下文环境当中的单个进程的事件&#x…

入门编程的方法和步骤

编程是信息时代必备的一项技能&#xff0c;无论是从事计算机行业的人员&#xff0c;还是从事其他行业的人员&#xff0c;学会编程对个人职业发展都有着重要的意义。但是&#xff0c;对于初学者来说&#xff0c;如何入门编程往往是一个比较棘手的问题。本文将介绍一些入门编程的…

训练YOLOv5对象检测模型的逐步指导

介绍 欢迎来到我们的 YOLOv5 教程系列的第 2 部分!如果您还没有查看本系列的第 1 部分,我建议您先阅读该部分;它涵盖了如何在 Windows 和 Google Colab 上安装用于真实对象检测的 YOLOv5 ,我们假设您已在本报告中完成了这些操作。 也就是说,一旦您设置了环境,您就可以开…

DuDuTalk语音工牌:语音数据分析在销售场景的应用价值

在现今这个数字时代&#xff0c;企业需要更高效、更有效地沟通和合作。语音数据的收集和分析能够增加销售团队和客户之间的联系&#xff0c;同时提高销售闭合率。因此&#xff0c;了解和利用销售沟通语音数据的价值&#xff0c;是现代企业所必须的。 销售沟通语音数据指的是在…

精益生产管理的优势特点以及工具步骤

一、何为精益生产 精益生产&#xff08;LeanProduction&#xff0c;简称LP&#xff09;是美国麻省理工学院数位国际汽车计划组织&#xff08;IMVP&#xff09;的专家对日本“丰田JIT&#xff08;JustInTime&#xff09;生产方式”的赞誉之称&#xff0c;精&#xff0c;即少而精…

不同股指期货交易平台的优缺点比较,让你一目了然!

股指期货交易平台是股指期货交易的重要场所&#xff0c;是期货市场的核心平台之一。在股指期货交易平台上&#xff0c;投资者可以进行股指期货的买卖&#xff0c;获得相应的投资收益。然而&#xff0c;对于大部分投资者来说&#xff0c;如何选择一个好的股指期货交易平台却是一…

locust压测脚本文档组织结构

以下为locust压测脚本文档组织结构模板&#xff0c;和TestDeploy对接丝滑&#xff0c;轻松实现分布式压测。 1、common common主要是存放改写了的请求方法&#xff0c;包括GET、POST等等&#xff0c;作为统一入口&#xff0c;以便各个API统一调用。 2、config config主要存…

读取PPT模板替换数据生成PDF报表

一、项目背景 因本人的公司是做短信通信服务的&#xff0c;所以客户需要将短信的发送量&#xff0c;按照他们给定的PPT样例模板&#xff0c;来生成PDF报表数据&#xff0c;即PPT的样式&#xff0c;数据如何展示都是规定好了的&#xff0c;而我需要做的就是将真实的数据&#xf…

B站参战618,直播带货成变现香饽饽,直播数据分析必看

五月已经见底&#xff0c;年中电商大考“618购物节”自26号拉开序幕。 各大主播、平台、品牌都紧锣密鼓地布起活动网。去年&#xff0c;B站因首次参战双十一冲上热门&#xff0c;平台为此上线直播购物分区。 来源-B站 经过去年各大品牌、UP主对双十一购物节直播带货的试水、观…

LCR测试仪夹具选型指南新鲜出炉

好马配好鞍&#xff0c;好仪器配好夹具。有不少朋友好奇&#xff0c;仪器选好了&#xff0c;那测试夹具如何挑选&#xff1f; 接下来安泰测试为大家简单介绍一下关于LCR测试仪中常用的测试夹具。 1/ 四端/四端对测试线 01 TH26011AS 频率范围&#xff1a;5Hz-100kHz 最大…

火山引擎DataLeap:如何构建一套完整、易用的数据标准体系

数据标准是数据治理体系中的核心要素之一。 一方面&#xff0c;统一的数据标准可以在复杂的业务场景下&#xff0c;帮助团队对齐数据口径&#xff0c;提升数据在分析、诊断等场景的质量与效率&#xff1b;另一方面&#xff0c;数仓团队与分析师团队也需要沉淀一套敏捷、可控的…

TimSort——最快的排序算法

TimSort——最快的排序算法 排序算法是每个程序员绕不开的课题&#xff0c;无论是大学课程还是日常工作&#xff0c;都离不开排序算法。常见的排序算法有&#xff1a;冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、基数排序等。下面是这些算法性能的概…

2022年天府杯全国大学生数学建模竞赛D题高等院校综合发展状况与学科质量评估解题全过程文档及程序

2022年天府杯全国大学生数学建模竞赛 D题 高等院校综合发展状况与学科质量评估 原题再现&#xff1a; 问题背景&#xff1a;   高等院校是我国经济社会发展中的重要参与者&#xff0c;一流大学与一流学科的建成是实现社会主义共同富裕的重要基础。随着国家第二轮“双一流”…

PMP课堂模拟题目及解析(第16期)

151. 一个全球多学科项目的项目经理如何才能确保在所有学科中使用变更控制过程&#xff1f; A. 执行影响分析以考虑所有项目学科 B. 确保变更控制委员会有来自所有学科的代表 C. 邀请所有学科参加变更控制系统委员会会议&#xff0c;但仅从所参加的学科收集意见 D. 代表其…

让你不再好奇图片识别工具怎么用

你是否曾经遇到过想知道一张照片中是什么物品或者景色&#xff0c;却不知道如何搜索的情况&#xff1f;或者&#xff0c;你是否曾经想要识别一张照片中的人脸&#xff0c;想要借助图片识别软件&#xff0c;又不知道图片识别工具怎么用&#xff1f;别担心&#xff0c;接下来我将…

「实在RPA·地产数字员工」筑牢数字经济发展之基

地产行业是国民衣食住行日常生活中的重要组成部分&#xff0c;为人们提供遮风挡雨的温暖港湾。根据国家统计局数据&#xff0c;从GDP占比看&#xff0c;2020年房地产及其产业链占我国GDP的17%&#xff08;完全贡献&#xff09;&#xff0c;是我国经济发展的火车头之一。由此看来…

零代码、低代码、APaaS系统怎么选?一文带你避坑!

零代码、低代码、apaas的概念在整个全球行业内已经流行了很长一段时间。那这3个概念分别指的是什么&#xff1f;他们具备何种能力&#xff1f;企业如果要用该如何选&#xff1f;有哪些好用的低代码平台推荐&#xff1f;下面一文全部给你讲清楚&#xff01; 一、零代码、低代码…

HTML+CSS实训——Day07——发现页用JavaScript进一步修改

仓库链接:https://github.com/MengFanjun020906/HTML_SX 前言 继续改昨天的界面&#xff0c;我们在上周写的都是静态页面&#xff0c;这周开始给静态界面加上javascript&#xff0c;可以让其互相跳转&#xff0c;再加上一些功能。 Find.html // 歌曲列表let songs [{"s…

Java 集合List转 Map 和Map转List的方法总结(举例说明!)

最近遇到了一个场景是&#xff0c;要将从数据库中查出的List<bean>转换为List<map>然后再取map中的value&#xff0c;最后把所有的value写到Excel中。由于这个bean的属性太多了&#xff0c;我最开始没有采用list转map的方式取获取value&#xff0c;而是在for循环中…

结构型设计模式03-外观模式

✨作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 外观模式&#xff08;门面模式&#xff09; 1、外观模式介绍 外观模式&#xff08;Facade Pattern&#xff09;&#xff0c;也称门…