5、设计模式应用举例:观察者模式:统计文本中的单词和数字

C++学生信息管理系统:面向对象设计、STL容器与文件持久化实战 面向对象编程是构建复杂软件系统的核心范式,它通过封装、继承和多态等机制,将数据和操作组织成对象,从而提升代码的可维护性和复用性。其原理在于将现实世界的实体抽象为类,并通过对象间的交互实现业务逻辑。在C++等语言中,这一技术价值体现在能够构建模块化、高内聚低耦合的系统架构。学生信息管理系统是经典的实践应用场景,它要求开发者将面向对象思想与具体数据结构、文件I/O等基础技术结合。本文以C++实现为例,深入探讨了如何运用STL容器(如std::map)高效管理数据,并通过二进制序列化解决文件持久化中的变长字符串存 阅读详情

目录

零、关于观察者模式:

一、设计要求

二、设计实现

1、主题

2、观察者

3、具体主题

4、具体观察者

5、应用程序

三、执行效果


零、关于观察者模式:

设计模式:5、观察者模式(发布-订阅模式)_发布模式 uml-优快云博客

一、设计要求

  1. 设计一个窗口,该窗口中有三个文本区。
  2. 三个文本区中的其中一个可供用户编辑文本,另外两个用户不可编辑。
  3. 当用户在可编辑的文本中进行文本编辑操作时,另外两个不可编辑文本区中的一个将显示用户所编辑文本中出现的单词,另一个将显示用户所编辑文本中所包含的数字

二、设计实现

1、主题

本问题中,使用java.util包中的Observable类作为主题

2、观察者

观察者是Java.util包中的Observer接口

3、具体主题

InputTextSubject是Observerble类的子类,负责创建具体主题。InputTextSubject类包含一个可编辑的JTextArea文本区,代码如下:

package xyz.jangle.design.app.observer;

import java.util.Observable;

import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * 	具体主题
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2026年10月10日 下午3:34:39
 * 
 */
@SuppressWarnings("deprecation")
public class InputTextSubject extends Observable {
	
	String content;
	JTextArea text;
	public InputTextSubject() {
		
		text = new JTextArea(10, 15);
		text.setLineWrap(true);
		text.setWrapStyleWord(true);
		(text.getDocument()).addDocumentListener(new DocumentListener() {
			
			@Override
			public void removeUpdate(DocumentEvent e) {
				changedUpdate(e);
			}
			
			@Override
			public void insertUpdate(DocumentEvent e) {
				changedUpdate(e);
			}
			
			@Override
			public void changedUpdate(DocumentEvent e) {
				content = text.getText();
				setChanged();
				notifyObservers(content);
			}
		});
		
	}
	
	public String getContent() {
		return content;
	}
	
	public JTextArea getJTextArea() {
		return text;
	}
	

}

4、具体观察者

负责创建具体观察者的类是ShowWord和ShowDigit,代码如下:

package xyz.jangle.design.app.observer;

import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.TreeSet;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2026年10月10日 下午3:41:48
 * 
 */
@SuppressWarnings("deprecation")
public class ShowWord extends JPanel implements Observer {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 3141650329393665296L;
	Observable subject;
	JTextArea text;
	TreeSet<String> wordList;
	
	

	public ShowWord(Observable subject) {
		super();
		this.subject = subject;
		subject.addObserver(this);
		text = new JTextArea(10, 15);
		text.setLineWrap(true);
		text.setWrapStyleWord(true);
		text.setEditable(false);
		add(new JScrollPane(text));
		wordList = new TreeSet<String>();
	}



	@Override
	public void update(Observable o, Object arg) {
		text.setText(null);
		text.append("出现的单词有(按字典序排序)");
		wordList.clear();
		String content = arg.toString();
		String regex = "[\\s\\d\\p{Punct}]+";
		String words[] = content.split(regex);
		for(int i = 0;i<words.length;i++) {
			wordList.add(words[i]);
		}
		Iterator<String> iterator = wordList.iterator();
		while(iterator.hasNext()) {
			text.append(iterator.next() + " ");
		}

	}

}
package xyz.jangle.design.app.observer;

import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2026年10月10日 下午3:57:13
 * 
 */
@SuppressWarnings("deprecation")
public class ShowDigit extends JPanel implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 68790415105796644L;
	Observable subject;
	JTextArea text;
	Vector<String> vector;
	

	public ShowDigit(Observable subject) {
		super();
		this.subject = subject;
		this.subject.addObserver(this);
		text = new JTextArea(10, 15);
		text.setLineWrap(true);
		text.setWrapStyleWord(true);
		text.setEditable(false);
		add(new JScrollPane(text));
		vector = new Vector<String>();
	}


	@Override
	public void update(Observable o, Object arg) {
		text.setText(null);
		text.append("出现的数字有:\n");
		vector.removeAllElements();
		String content = arg.toString();
		String regex = "\\D+";	// 非数字字符构成的正则表达式
		String digitWords[] = content.split(regex);
		for(int i=0;i<digitWords.length;i++) {
			if(!vector.contains(digitWords[i])) {
				vector.add(digitWords[i]);
			}
		}
		for(int i=0;i<vector.size();i++) {
			text.append(vector.elementAt(i)+ " ");
//			vector.get(i);
		}

	}

}
5、应用程序
package xyz.jangle.design.app.observer;

import java.awt.FlowLayout;
import java.awt.HeadlessException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;

/**
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2026年10月10日 下午4:08:33
 * 
 */
public class Application extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1766425301653051370L;

	public Application() throws HeadlessException {
		super();
		InputTextSubject inputTextSubject = new InputTextSubject();
		ShowWord observerOne = new ShowWord(inputTextSubject);
		ShowDigit observerTwo = new ShowDigit(inputTextSubject);
		setLayout(new FlowLayout());
		
		add(new JScrollPane(inputTextSubject.getJTextArea()));
		
		add(observerOne);
		add(observerTwo);
		setBounds(20, 20, 400, 300);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		
		new Application();

	}

}

三、执行效果

软件工程术语辨析:编码、设计与代码评审的常见误区 在软件工程实践中,术语的准确理解是高效沟通的基础。以“编码”为例,它既指代码编写(coding),也指字符编码规则(encoding),还涵盖信息论中的压缩编码算法,同一词汇在不同上下文中的含义差异巨大。与此同时,设计领域的内聚与耦合、SOLID原则、设计模式,以及代码评审中的Blocking、Nit等术语,也常常被误读或滥用。理解这些概念的本质原理,不仅能提升代码质量,还能显著降低团队协作成本。无论是处理乱码问题、优化模块设计,还是进行代码重构,清晰统一的术语体系都是工程实践的重要支撑。本文从软件工程基础 阅读详情

相关推荐

C++面试八股文常见错误勘误:从constexpr到ABA问题

C++作为高性能系统级编程语言,其语法细节与并发模型始终是开发者关注的焦点。在面试准备中,常因资料错误导致对constexpr引入版本、CAS操作与ABA问题等核心概念产生误解。理解这些底层原理不仅有助于写出更健壮的代码,也能在工程实践中正确运用内存模型、原子操作与智能指针。从基础语法到多线程编程,再到算法复杂度与设计模式,系统梳理这些高频考点的本质,能帮助开发者避开常见误区,真正提升技术判断力与工程实践能力。本文基于实际面试经验,对多个常见错误进行逐一勘误,并给出更符合现代C++标准的理解方式,助你构建更

weixin_30861797的博客 553

秒杀启动为何必须用观察者模式+Quartz协同设计

观察者模式是一种解耦状态变更与响应行为的经典设计模式,其核心在于将‘事件通知’与‘业务处理’分离,从而支撑高可维护、易扩展、可测试的系统架构;Quartz则作为精准时间调度组件,为观察者提供毫秒级触发能力,二者分层协作——前者解决‘谁来响应’,后者解决‘何时响应’。这种组合在电商秒杀等强时效、多系统协同场景中,显著提升启动一致性、降低跨团队耦合、增强故障隔离能力,并天然支持灰度发布、死信处理与优先级编排,是构建可靠状态驱动型服务的关键技术范式。

weixin_29882269的博客 271

《Python3案例和总结》-专栏介绍和目录

本专栏专注于Python基础和进阶的系统讲解,逐步深入实际应用场景到python高级特性,让你轻松学会用Python解决各种实际问题。不管是零基础还是有经验的开发,相信都能从本专栏获益。

数据知道的博客 1万+

JavaScript对象全解析:从基础到高级应用

JavaScript对象是这门语言的核心数据结构,作为键值对的集合,它既能存储结构化数据,又能封装行为方法。从原型继承机制到ES6的Proxy反射,对象系统支撑着JS的面向对象编程范式。在实际开发中,对象既可作为配置容器,也能实现哈希表快速查找,还能通过工厂模式、观察者模式等设计模式构建复杂系统。掌握属性描述符、深拷贝、WeakMap等高级特性,能有效提升代码质量并避免常见陷阱。现代前端开发中,对象与TypeScript类型系统的结合,以及Map/Set等替代方案的选择,都是工程师需要权衡的技术决策点。

weixin_30340819的博客 394

fMRI数据处理:从DICOM到NIFTI(下)

上一篇我们完成了对原始DICOM的数据整理,将其整理为了BIDS目录结构。作为从从DICOM到NIFTI的最后一篇,当然是介绍如何批量将DICOM格式转NIFTI格式啦!从DICOM到NIFTI系列就完成啦!撒花★,°.°★。从核磁机器把数据拷回来——到整理成BIDS格式——到批量转格式;我们fMRI数据处理的第一步就算是正式迈出去啦!接下来的内容,敬请期待吧~

weixin_44933894的博客 2078

stackelberg博弈_博弈论、多智能体、强化学习(随便记点东西)

多智能体应用场景:已实现:游戏AI。正在努力:UAV,物资运输,快递分发,交通系统。未来:社会学,预测群体行为,城市区域合作,国际关系。博弈论基本定义:玩家集合: 策略集合: 收益函数: 囚徒困境:两智能体矩阵博弈坦白抵赖坦白1,13,0抵赖0,32,2占优策略与最佳应对:上表中两者均具有占优策略,即无论如何都应该选坦白。那么构造下表。坦白抵赖坦白1,13,0抵赖0,12,2对于玩家一来说,坦白...

weixin_39611722的博客 2995

全网最新阿里巴巴面试通关手册:学习笔记+算法宝典+面试题库

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。再分享一波我的Java面试真题+视频学习详解+技能进阶书籍《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!” />对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

erghtt的博客 616

解决 Clawdbot 对接 Minimax 出现 401 (Token is unusable) 的问题排查与修复

即便确认 API Key 有效且余额充足,该问题仍可能在 Clawdbot 中持续出现,而在其他工具(如 curl 或 Postman)中测试正常。

hampeter的博客 3072

Java面试必备:阿里首发面试通关宝典震撼开源,文档

什么是守护线程? join ()方法的作用是什么? 如何通过JDBC访问数据库? JDBC处理事务采用什么方法? Class.forName的作用是什么? Statement、PreparedStatement和CallableStatement有什么区别? getString ()方法与getObject ()方法有什么区别? 使用JDBC时需要注意哪些问题? 什么是JDO? JDBC与Hibernate有什么区别? … 2.Java Web Serv..

m0_69379068的博客 154

告别误唤醒!S32K3xx低功耗设计避坑指南:Fast Standby模式与WISR寄存器操作详解

本文深入解析了NXP S32K3xx系列MCU在低功耗设计中常见的误唤醒问题,并提供了基于Fast Standby模式的解决方案。文章重点剖析了DCMRWF5寄存器的配置方法、WISR/WISR_64唤醒中断状态寄存器的标志位处理策略,以及如何利用32KB Standby SRAM保存唤醒状态,从而帮助开发者构建稳定可靠的汽车电子低功耗系统。

weixin_29163857的博客 361

电赛控制-----经验分享

1.赛前准备 先简单介绍一下电赛。电赛是两年一届,单数年是大电赛,全称是全国大学生电子设计大赛,之前由瑞萨电子赞助,所以之前也叫瑞萨杯,从19年开始赞助方变成了TI公司,偶数年是小电赛,全称是“TI杯”模电邀请赛,(这里不得不提TI公司的实力是愈来愈大了),一般来说小电赛的含金量会略低于大电赛,而且对与想拿国奖的同学来说还是要参加大电赛,因为小电赛一般每个学校会限制只有两个队伍进国赛,而大电赛是没有这个限制的,而且我们学校电赛保研的话,大电赛只要求国二,而小电赛只有国一才可以保,这样难度就增加了很多。..

qq_35656655的博客 1万+

Java面试必备:阿里首发面试通关宝典震撼开源,文档+面试真题+面试技巧+心得全都有(1)

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考以下是部分内容截图网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)一个人可以走的很快,但一群人才能走的更远!

2401_84411929的博客 526

Cocos Creator发布微信小游戏:深度定制与去除默认加载页面的实践指南

本文详细介绍了如何使用Cocos Creator发布微信小游戏时去除默认加载页面的实践方法。通过修改构建配置和重写启动逻辑,开发者可以自定义加载体验,提升品牌一致性。文章还提供了进阶优化方案和常见问题解决方案,帮助开发者实现更专业的微信小游戏发布流程。

weixin_27972919的博客 565

全网最新阿里巴巴面试通关手册:学习笔记+算法宝典+面试题库(1)

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)

2401_84424649的博客 964

A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[五]-GeniePath会自动过滤多度“邻居“的图神经网络算法。

构图对于GNN格外重要。那么怎样构图才有信息、有意义呢?如果节点的邻居只有自己,即邻接矩阵为对角阵时,GNN会退化成一个DNN模型。图中每个节点都是孤立的,相当图信息并不能相比其他方法带来增益。如果图特别稠密,比如是一个clique,即每个节点都和所有其他节点有边连接。同样的,这样的图信息同样是信息熵为0。经验上讲,节点度分布有区分度的图是相对有价值的。查看图的节点度分布。比如二类分类,分析正负例的图拓扑当然,构图和实际场景强相关。

丨汀、的博客 437

【Android逆向工程】第18章:Ollvm 混淆与对抗

本章介绍了Ollvm混淆技术及其对抗方法。Ollvm是基于LLVM的开源代码混淆工具,主要实现控制流平坦化、虚假控制流和指令替换三种混淆技术。控制流平坦化通过状态变量和switch-case结构隐藏真实控制流,将原本清晰的逻辑拆分为多个状态块。混淆后的代码在静态分析中难以理解,但可通过动态追踪执行路径、符号执行等方法来还原原始逻辑。本章还提供了混淆代码示例和对抗策略,帮助理解Ollvm的工作原理及其防御方法。

w987333120的博客 213

我能斩获自己跳动offer,全靠在一周内肝完这426页阿里面试通关手册,(1)

1.webpack打包文件体积过大?(最终打包为一个js文件)2.如何优化webpack构建的性能3.移动端的性能优化4.Vue的SPA 如何优化加载速度5.移动端300ms延迟6.页面的重构所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

2401_84436058的博客 1013

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

最新全网最新阿里巴巴面试通关手册:学习笔记+算法宝典+面试题库,rocketmq原理解析

算法部分:(1)一个长度为n的数组,元素在1到n之间,找到一个重复的元素,空间复杂度越低越好;祝愿,明年的你会更好!

2401_84103216的博客 908

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++入门指南:从环境搭建到STL应用,掌握编程底层思维

编程语言是计算机科学的基础工具,其核心在于理解计算机如何执行指令和管理数据。C++作为一门接近底层的编译型语言,通过直接操作内存和CPU指令,能够帮助开发者建立对计算机系统原理的深刻认知。这种底层理解是学习高级语言特性的基础,例如Java的垃圾回收机制和Python的动态类型系统。在工程实践中,掌握C++意味着能够编写高性能、资源可控的应用程序,尤其在系统编程、游戏开发和嵌入式领域具有不可替代的价值。通过系统学习C++,开发者不仅能熟练使用标准模板库(STL)中的容器和算法,还能理解面向对象编程的封装、继承

weixin_34220179的博客 470

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

我能斩获自己跳动offer,全靠在一周内肝完这426页阿里面试通关手册,

这次字节跳动的整个过程我就不去还原了,只将面试题分享出来吧,面试题以技术面为主,Hr面基本上大同小异我就省略掉了,可以参考一下今年字节跳动会问一些什么样的问题,热乎乎的新鲜面试题,希望能够给你带来一些帮助吧。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!Hibernate中session的update ()和saveOrUpdate ( ). load()和get ()有什么区别?request对象主要有哪些方法?

2401_84046912的博客 874

豆包聊天记录批量导出与角色拆分实战指南

AI对话数据导出是知识资产沉淀的基础能力,其本质涉及浏览器环境调试、WebSocket实时抓包、多层base64嵌套解码及结构化重建等关键技术。理解豆包无公开API的架构限制,可避免盲目调用Python爬虫导致的403拦截;掌握Chrome DevTools中WS消息监听与内存状态提取,是获取完整聊天树的前提。技术价值在于将黑盒式AI协作转化为可审计、可归档、可复用的本地知识库,支撑产品经理需求沉淀、开发者代码整理、教育工作者教学复盘等高频场景。本文聚焦豆包平台,提供从抓包到Markdown交付的端到端工程

weixin_34320159的博客 383

风筝制作基于HarmonyOS ArkTS API 24全栈解析,TAB_LIST 常量是一个包含六个 TabMeta 对象的数组,按照风筝制作的工艺流程顺序排列

健身管理类应用与之前分析的外卖、招聘等应用有本质差异——它的核心数据不是"交易"或"任务",而是"时间序列的身体状态数据":每次训练有时长、卡路里、组数、重量;每次饮食有热量、蛋白质、碳水、脂肪;每周有运动时长趋势图。这些数据的共同特征是"随时间积累,用户需要横向对比和趋势分析"。这导致健身App的数据层设计必须从第一天就考虑"历史数据查询"和"多维度聚合"的需求,而非仅关注当前单条记录的增删改查。健身应用的用户行为模式也有独特之处:用户使用健身App的目标是"坚持",而不是"一次性完成任务"。这意味着激励

jin421352的博客 181
上一篇: 在tomcat应用里添加了一个线程池对象,向这个线程池发送任务,让其执行。 我希望在tomcat停机时,能等待线程池里的任务执行完了再停机,要如何实现?
下一篇: 6、设计模式应用举例:装饰模式:读取单词表
博风
博客等级 码龄16年 442粉丝 357原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值