【行为型模式】观察者模式

一、观察者模式概述​

        软件系统其实有点类似观察者模式,目的:一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,他们之间将产生联动

        观察者模式

  •         1.定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象。
  •         2.发生改变的对象称为观察目标,被通知的对象成为观察者。
  •         3.一个观察目标可以对应多个观察者。别名:发布-订阅(Public/subscribe)模式,模型-视图(Model/View)模式,源-监听器(Source/Listener)模式,从属者(Dependents)模式。

        观察模式的优缺点

  •         优点
    • 1.可以实现表示层和数据逻辑层的分离。
    • 2.在观察目标和观察者之间建立了一个抽象的耦合。
    • 3.支持广播通信,简化了一对多系统设计的难度。
    • 4.符合开闭原则,添加新的具体观察者无须修改与原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
  •         缺点
    • 1.将所有的观察者都通知到会花费很多时间。
    • 2.如果存在循环依赖时可能会导致系统崩溃。
    • 3.没有相应得机制让观察者知道所观察得目标对象是怎么发生变化得,而只是知道观察目标发生了变化。
  •         适用环境
    • 1.一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将两个方面封装在独立得对象中方使它们可以各自独立地改变和复用。
    • 2.一个对象的改变将导致一个或多个其他对象发生改变,且并不知道具体有多少个对象将发生改变,也不知道这些对象是谁。
    • 3.需要在系统中创建一个触发链。

二、代码实现

  主题(Subject)+观察者(Observer)=观察者模式

        观察者模式的代码结构包含

  • 抽象主题(Subject):接口,抽象类;
  • 具体主题(ConcreteSubject):比如公众号;
  • 抽象观察者(Observer);
  • 具体观察者(ConcreteObserver);
        2.1 战队控制实现代码
        2.1.1 抽象主题用抽象类实现(抽象类类名AllyControlCenter)
package Observe.ally;import java.util.*;//战队控制中心类:目标抽象类
public abstract class AllyControlCenter {protected String allyName;//战队名称//定义一个玩家集合protected ArrayList<Observer> players =new ArrayList<Observer>();public String getAllyname() {return allyName;}public void setAllyname(String allyName) {this.allyName = allyName;}//注册方法public void join(Observer obs) {System.out.println(obs.getName()+"加入"+this.allyName+"战队!");players.add(obs);}//注销方法public void quit(Observer obs) {System.out.println(obs.getName()+"退出"+this.allyName+"战队!");players.remove(obs);}//声明抽象通知方法public abstract void notifyObserver(String name);
}
        2.1.2 具体主题实现(ConcreteAllyControlCenter)
package Observe.ally;public class ConcreteAllyControlCenter extends AllyControlCenter {public ConcreteAllyControlCenter(String allyName) {System.out.println(allyName+"战队组建成功!");System.out.println("-------------------------");this.allyName = allyName;}@Overridepublic void notifyObserver(String name) {// TODO 自动生成的方法存根System.out.println(this.allyName+"战队紧急通知,盟友"+name+"遭受敌人袭击!");//遍历观察者集合,调用每一个盟友(自己除外)的支援方法for(Object obs : players) {if(!((Observer)obs).getName().equalsIgnoreCase(name)) {((Observer)obs).help();}}}}
        2.1.3 抽象观察类(接口实现,接口名为Observer)
package Observe.ally;
//抽象观察类
public interface Observer {public String getName();public void setName(String name);public void help();//声明支援盟友方法//声明遭受攻击方法public void beAttacked(AllyControlCenter acc);
}
        2.1.4 具体观察者(Player)
package Observe.ally;public class Player implements Observer{private String name;public Player(String name) {this.name =name;}public String getName() {return name;}public void setName(String name) {this.name = name;}//支援盟友方法的实现public void help() {System.out.println("坚持住:"+this.name+"来救你!");}//遭受攻击方法的实现,当遭受攻击时将调用战队控制中心的通知方法notifyObserver()来通知public void beAttacked(AllyControlCenter acc) {System.out.println(this.name+"被攻击!");acc.notifyObserver(name);}
}
        2.1.5 main方法调用实现观察者模式
package Observe.ally;public class Client {public static void main(String[] args) {// TODO 自动生成的方法存根//定义观察者目标对象AllyControlCenter acc;acc= new ConcreteAllyControlCenter("金庸群侠");//定义四个观察者对象Observer player1,player2,player3,player4;player1 = new Player("杨过");acc.join(player1);player2 = new Player("令狐冲");acc.join(player2);player3 = new Player("张无忌");acc.join(player3);player4 = new Player("段誉");acc.join(player1);//某成员遭受攻击player1.beAttacked(acc);}}
        2.1.6 UML图

        2.2 公众号代码实现
        2.2.1 抽象主题用抽象接口实现(抽象接口名Subject)
package Observe.Weixin_observation;
//公众号,主题对象
public interface Subject {//注册public void registerObserver(Observer o);//删除public void removeObserver(Observer o);//通知用户public void notifyObservers(String message);
}
        2.2.2 具体主题实现(WeixinSubject
package Observe.Weixin_observation;import java.util.*;public class WeixinSubject implements Subject {private List<Observer> users = new ArrayList<Observer>();String msg;@Overridepublic void registerObserver(Observer o) {// TODO 自动生成的方法存根users.add(o);}@Overridepublic void removeObserver(Observer o) {// TODO 自动生成的方法存根int i = users.indexOf(o);if(i>=0)users.remove(i);}@Overridepublic void notifyObservers(String message) {// TODO 自动生成的方法存根//冒号表示范围==Observer必须在users里面for(Observer o:users) {o.update(message);}}//更新信息public void setMsg(String msg) {this.msg = msg;notifyObservers(msg);}
}
        2.2.3 抽象观察类(接口实现,接口名为Observer)
package Observe.Weixin_observation;public interface Observer {//发送文本信息,推送public void update(String message);
}
        2.2.4 具体观察者(WeixinUser)
package Observe.Weixin_observation;public class WeixinUser implements Observer {String name;public WeixinUser(String name) {super();this.name = name;}@Overridepublic void update(String message) {// TODO 自动生成的方法存根System.out.println(name+",您好!"+message);}//关注/订阅公众号public void subscribeSubject(Subject o) {o.registerObserver(this);}//取消订阅public void deleteSubject(Subject o) {o.removeObserver(this);}
}
        2.2.5 main方法调用实现观察者模式
package Observe.Weixin_observation;public class Test {public static void main(String[] args) {// TODO 自动生成的方法存根//创建一个微信公众号WeixinSubject hdjdlgxydxfy = new WeixinSubject();WeixinUser user1 = new WeixinUser("user1");WeixinUser user2 = new WeixinUser("user2");WeixinUser user3 = new WeixinUser("user3");//用户关注user1.subscribeSubject(hdjdlgxydxfy);user2.subscribeSubject(hdjdlgxydxfy);user3.subscribeSubject(hdjdlgxydxfy);//推送消息hdjdlgxydxfy.setMsg("学院2020年体育课开始选课拉.....");//取消订阅user1.deleteSubject(hdjdlgxydxfy);hdjdlgxydxfy.setMsg("学院2020年体育课结束,下面是选课名单...");}}
        2.2.6 UML图

三、代码结构图

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

说说你对集合的理解?常见的操作有哪些?

一、是什么 集合&#xff08;Set&#xff09;&#xff0c;指具有某种特定性质的事物的总体&#xff0c;里面的每一项内容称作元素 在数学中&#xff0c;我们经常会遇到集合的概念&#xff1a; 有限集合&#xff1a;例如一个班集所有的同学构成的集合无限集合&#xff1a;例如…

麒麟KOS删除鼠标右键新建菜单里不需要的选项

原文链接&#xff1a;麒麟KOS删除鼠标右键新建菜单里不需要的选项 Hello&#xff0c;大家好啊&#xff01;在日常使用麒麟KOS操作系统时&#xff0c;我们可能会发现鼠标右键新建菜单里包含了一些不常用或者不需要的选项。这不仅影响我们的使用效率&#xff0c;也让菜单显得杂乱…

【3DsMax+Pt】练习案例

目录 一、在3DsMax中展UV 二、在Substance 3D Painter中绘制贴图 一、在3DsMax中展UV 1. 首先创建如下模型 2. 选中如下三条边线作为接缝 重置剥 发现如下部分还没有展开 再选一条边作为接缝 再次拨开 拨开后的UV如下 二、在Substance 3D Painter中绘制贴图 1. 新建项目&am…

多乐空气处理设备有限公司现已加入2024第13届生物发酵展

参展企业介绍 为满足日益发展的中国大陆市场对环境的要求&#xff0c;更接近Zui终用户&#xff0c;多乐集团于2001年在上海松江设立了第一家生产基地。经过十数年来的高速发展&#xff0c;多乐以其精湛的加工工艺、yiliu的制造技术方面的优势&#xff0c;在对温度湿度有严格要…

DAY14|二叉树理论基础、递归遍历、迭代遍历、统一迭代

理论基础、递归遍历、迭代遍历、统一迭代 理论基础递归遍历迭代遍历前序中序后序 统一迭代 理论基础 今天的内容极其基础也极其重要&#xff0c;今天的不掌握好&#xff0c;之后一个半月都要坐大牢… 以前算法课上学的还行&#xff0c;可能还能记得一些&#xff08;希望&#…

ubuntu 使用conda 创建虚拟环境总是报HTTP错误,转换多个镜像源之后仍报错

最近在使用Ubuntu conda创建虚拟环境时&#xff0c;总是报Http错误&#xff0c;如下图所示&#xff1a; 开始&#xff0c;我以为是conda 镜像源的问题&#xff0c;但是尝试了好几个镜像源都不行&#xff0c;还是报各种各样的HTTP错误。后来查阅很多&#xff0c;总算解决了。解…

imx6ull官方源码linux内核移植

1.尝试官方源码 在正点原子给的资料里找到NXP官方原版linux源码&#xff0c;路径为&#xff1a; 1、例程源码->4、 NXP 官方 原版 Uboot和 Linux->linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。复制并解压。 修改顶层Makefile 编译一下 make -j16 出现以下错误 修改 就…

【数据结构】树与二叉树、树与森林部分习题以及算法设计例题 2

目录 【数据结构】树与二叉树、树与森林部分习题以及算法设计例题一、交换二叉树每个结点的左右孩子Swap 函数&#xff08;先序遍历&#xff09;&#xff1a;Swap 函数&#xff08;中序遍历&#xff09; 不可行&#xff1a;Swap 函数&#xff08;后序遍历&#xff09;&#xff…

【开发篇】十三、JVM基础参数设置与垃圾回收器的选择

文章目录 1、-Xmx 和 –Xms2、-XX:MaxMetaspaceSize 和 –XX:MetaspaceSize3、-Xss4、不建议改的参数5、其他参数6、选择GC回收器的调试思路7、CMS的并发模式失败现象的解决8、调优案例 GC问题解决方式&#xff1a; 优化JVM基础参数&#xff0c;避免频繁Full GC减少对象的产生…

0基础如何入门编程?

0基础如何进入IT行业 &#xff1f; 前言 简介&#xff1a;对于没有任何相关背景知识的人来说&#xff0c;如何才能成功进入IT行业&#xff1f;是否有一些特定的方法或技巧可以帮助他们实现这一目标&#xff1f; 主要方法有如下几点建议提供给宝子们 目录 免费视频网课学习…

读书笔记之《如何精心设计提示词来精通ChatGPT》

《如何精心设计提示词来精通ChatGPT》这本书英文标题为&#xff1a;《The Art of Prompt Engineering with chatGPT》&#xff0c;于2023年出版。作者是Nathan Hunter 。 Nathan Hunter简介&#xff1a;ChatGPT培训的创始人。作为一名资深培训师和教学设计师&#xff0c;我在过…

Spring Cloud 集成 Redis 发布订阅

目录 前言步骤引入相关maven依赖添加相关配置 使用方法发布订阅发布一个消息 注意总结 前言 在当今的软件开发领域&#xff0c;分布式系统已经成为一种主流的架构模式&#xff0c;尤其是在处理大规模、高并发、高可用的业务场景时。然而&#xff0c;随着系统复杂性的增加&…

elementor和divi的对比,哪个更适合你,他们国产化替代方案

Elementor和Divi都是流行的WordPress页面构建器&#xff0c;它们各自具有一些独特的优点和缺点。现在有越来越多的应用服务商开发了自助建站工具&#xff0c;通过自助建站工具&#xff0c;我们可以轻松的创建一个看起来很专业的网站。但在眼花缭乱的软件产品面前&#xff0c;我…

SpringMVC(三)【REST 风格】

1、REST 风格 1.1、REST 简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换 在开发中&#xff0c;它其实指的就是访问网络资源的格式 1.1.1、传统风格资源描述形式 http://localhost/user/getById?id1http://localhost/user…

数据结构——栈(C++实现)

数据结构——栈 什么是栈栈的实现顺序栈的实现链栈的实现 今天我们来看一个新的数据结构——栈。 什么是栈 栈是一种基础且重要的数据结构&#xff0c;它在计算机科学和编程中扮演着核心角色。栈的名称源于现实生活中的概念&#xff0c;如一叠书或一摞盘子&#xff0c;新添加…

【C++初阶】C++简单入门(长期维护)

本篇博客是对C的一些简单知识分享&#xff0c;有需要借鉴即可。 C简单入门目录 一、C前言1.C的概念&#xff1a;2.C发展历程3.C如何学&#xff1f; 二、C入门1.C关键字(C98标准)2.命名空间3.C输入&输出①概念说明②使用说明③特征说明④细节拓展⑤cout与cin的意义 4.缺省参…

处理json文件,并将数据汇总至Excel表格

从scores.jason文件中读取学生信息,输出学生的学号&#xff0c;姓名&#xff0c;各科成绩&#xff0c;平均分, 各科标准差 scores.jason {"学院": "计算机学院","班级": "2022级1班","成绩": [{"学号": 1001,&q…

【vue】绑定事件 v-on

v-on 简写&#xff1a; clickkeyupkeydownkeyup.wkeyup.ctrl.a <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

BK9534 博通BEKEN 无线麦克风芯片 提供配置工具软件

BK9534 芯片是在 BK9532 芯片基础上增加了一个内置MCU 来实现单芯片简单工作模式&#xff0c;内置己经固化了如开关机&#xff0c;对码&#xff0c;低电侦测&#xff0c;自动频率跟随等基本功能。另外还可以借助工具修改如频率&#xff0c;ID等相关配置信息. 1. 升级了接收芯片…

SpringBoot修改菜品模块开发

需求分析与设计 一&#xff1a;产品原型 在菜品管理列表页面点击修改按钮&#xff0c;跳转到修改菜品页面&#xff0c;在修改页面回显菜品相关信息并进行修改&#xff0c;最后点击保存按钮完成修改操作。 修改菜品原型&#xff1a; 二&#xff1a;接口设计 通过对上述原型图…