JAVA:深入了解JAVA中的23种设计模式(三)- 行为型模式(下)
一、前言
在前三篇 《深入了解JAVA中的23种设计模式(一)- 创建型模式》 《深入了解JAVA中的23种设计模式(二)- 结构型模式》 《深入了解JAVA中的23种设计模式(三)- 行为型模式(上)》 中介绍了Java中的23种设计模式的创建型模式、结构型模式与行为型模式中的一些设计模式,本文将继续讲解行为型模式剩下的设计模式。
二、行为型模式(下)
1. 备忘录模式
1.1 简介
在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将对象恢复到原先保存的状态。
1.2 使用场景
需要保存和恢复数据的相关状态场景。
提供一个可回滚(rollback)的操作。
需要监控的副本场景中。
数据库连接的事务管理就是用的备忘录模式。
1.3 代码示例
/ 发起
public class Originator { private String state; public void setState(String state) { this.state = state; } public String getState() { return state; } // 创建备忘录 public Memento createMemento() { return new Memento(state); } // 使用备忘录恢复状态 public void restoreMemento(Memento memento) { this.state = memento.getState(); }
} // 备忘录
public class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; }
} // 管理者
public class Caretaker { private Memento memento; public void setMemento(Memento memento) { this.memento = memento; } public Memento getMemento() { return memento; }
}
2. 状态模式
2.1 简介
允许一个对象在其内部状态改变时改变它的行为,对象看起来好像修改了它的类。其核心思想是将状态与行为绑定,不同的状态对应不同的行为。当控制一个对象状态的条件表达式过于复杂时,状态模式可以将状态的判断逻辑转移到表示不同状态的一系列类中,从而简化复杂的判断逻辑。
2.2 使用场景
当对象的行为与其当前状态密切相关,且需要在运行时根据状态改变行为时,可以使用状态模式。
当一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态时,状态模式可以简化代码并提高可维护性。
当需要避免使用大量的条件语句来控制对象的行为时,状态模式可以提供一种更加优雅的解决方案。
2.3 代码示例
/抽象状态角色
public abstract class Status {//定义一个角色,提供子类访问protected Context context;//设置角色public void setContext(Context _context){this.context = _context;}//行为1public abstract void handle1();//行为2public abstract void handle2();
}
3. 访问者模式
3.1 简介
它表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。简单来说,访问者模式将数据操作与数据结构分离,使得在不修改数据结构的前提下,能为数据结构中的每个元素增加新的操作。
3.2 使用场景
当一个对象结构包含多个不同类型的对象,并且需要对这些对象执行不同的操作时,可以使用访问者模式。
当需要在不修改对象结构的情况下,添加新的操作或行为到对象中时,可以使用访问者模式。通过添加新的访问者类,可以实现新的操作,而无需修改现有的对象结构。
当对象结构中的对象类型相对稳定,但经常需要添加新的操作时,可以使用访问者模式。访问者模式使得添加新的操作变得简单,只需要创建新的访问者类即可。
当对象结构中的对象类型很少改变,但经常需要在这些对象上执行复杂操作时,可以使用访问者模式。访问者模式可以将复杂的操作分离出来,使得对象结构更加清晰和简单。
3.3 代码示例
// 访问者接口
interface Visitor { void visit(ElementA elementA); void visit(ElementB elementB);
} // 具体访问者类
class ConcreteVisitor implements Visitor { @Override public void visit(ElementA elementA) { System.out.println("访问 ElementA: " + elementA.getOperationA()); } @Override public void visit(ElementB elementB) { System.out.println("访问 ElementB: " + elementB.getOperationB()); }
} // 元素接口
interface Element { void accept(Visitor visitor);
} // 具体元素类 A
class ElementA implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } public String getOperationA() { return "ElementA 的操作"; }
} // 具体元素类 B
class ElementB implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } public String getOperationB() { return "ElementB 的操作"; }
} // 对象结构类
class ObjectStructure { private List<Element> elements = new ArrayList<>(); public void addElement(Element element) { elements.add(element); } public void accept(Visitor visitor) { for (Element element : elements) { element.accept(visitor); } }
}
4. 中介者模式
4.1 简介
该模式用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
4.2 使用场景
系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
4.3 代码示例
// 抽象中介者
public interface Mediator { void register(Colleague colleague); void relay(Colleague colleague, String message);
} // 具体中介者
public class ConcreteMediator implements Mediator { private List<Colleague> colleagues = new ArrayList<>(); @Override public void register(Colleague colleague) { if (!colleagues.contains(colleague)) { colleagues.add(colleague); } colleague.setMediator(this); } @Override public void relay(Colleague colleague, String message) { for (Colleague col : colleagues) { if (!col.equals(colleague)) { col.receive(message); } } }
} // 抽象同事类
public abstract class Colleague { protected Mediator mediator; public void setMediator(Mediator mediator) { this.mediator = mediator; } public abstract void receive(String message);
} // 具体同事类
public class ConcreteColleague extends Colleague { @Override public void receive(String message) { System.out.println("ConcreteColleague received message: " + message); } public void send(String message) { mediator.relay(this, message); }
}
5. 解释器模式
5.1 简介
提供了一种方式来定义语言的文法,并且建立一个解释器来解释该语言中的句子。这个模式定义了一个表示文法的类接口,以及一个解释这些文法的解释器接口。
抽象表达式(AbstractExpression):声明一个抽象的解释操作,这个接口为所有的具体表达式定义了一个统一的接口。
终结符表达式(TerminalExpression):实现了抽象表达式接口,并包含对文法中终结符的解释。
非终结符表达式(NonterminalExpression):实现了抽象表达式接口,并包含对文法中非终结符的解释。非终结符表达式通常还包含对其他表达式的引用。
环境(Context):包含解释器之外的一些全局信息,一般用来存储文法中各个终结符所对应的具体值。
客户端(Client):构建文法对应的抽象语法树,并调用解释器来解释文法。
5.2 使用场景
当有一个语言需要解释执行,并且该语言中的句子有比较简单的语法规则时,可以使用解释器模式。
当一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可以使用解释器模式。
当一个简单语法需要解释的场景也可以考虑使用解释器模式,如配置文件解析、数学表达式解析等。
5.3 代码示例
// 抽象表达式
interface Expression { int interpret(Context context);
} // 终结符表达式 - 数字
class NumberExpression implements Expression { private int value; public NumberExpression(int value) { this.value = value; } @Override public int interpret(Context context) { return value; }
} // 非终结符表达式 - 加法
class AdditionExpression implements Expression { private Expression left; private Expression right; public AdditionExpression(Expression left, Expression right) { this.left = left; this.right = right; } @Override public int interpret(Context context) { return left.interpret(context) + right.interpret(context); }
}
设计模式不是公式,没必要去死记硬背每一种模式,更重要的是了解它的抽象思想,以及应用设计模式怎么更好地解决问题,可以达成什么效果。理论虽多,但是我们要把它掌握的话,对于我们的实际开发来说会解决不少的问题。
相关文章:
JAVA:深入了解JAVA中的23种设计模式(三)- 行为型模式(下)
一、前言 在前三篇 《深入了解JAVA中的23种设计模式(一)- 创建型模式》 《深入了解JAVA中的23种设计模式(二)- 结构型模式》 《深入了解JAVA中的23种设计模式(三)- 行为型模式(上)》…...
微信小程序【WXML】
wxml wei xin markup language 类似于html 文档 数据绑定 小程序中使用{{}} 来进行数据绑定到模板中,如: wxml中的动态数据全部来自js中的data 简单绑定 //wxml <view> {{text }}</view>// index.js Page({data: {text: hello world}, })属性绑定…...
基于python实现的深度学习的车牌识别系统
基于python实现的深度学习的车牌识别系统 开发语言:Python 数据库:MySQL所用到的知识:Django框架工具:pycharm、Navicat、Maven 系统功能实现 登录页面 在车牌识别系统当中肯定是有登录的。怎么说呢,登录页面其实还是和最初的设…...
SQL试题使得每个学生 按照姓名的字⺟顺序依次排列 在对应的⼤洲下⾯
学⽣地理信息报告 学校有来⾃亚洲、欧洲和美洲的学⽣。 表countries 数据如下: namecontinentJaneAmericaPascalEuropeXiAsiaJackAmerica 1、编写解决⽅案实现对⼤洲(continent)列的 透视表 操作,使得每个学生 按照姓名的字⺟顺…...
kafka3.6.1版本学习
kafka目录结构 bin linux系统下可执行脚本文件 bin/windows windows系统下可执行脚本文件 config 配置文件 libs 依赖类库 licenses 许可信息 site-docs 文档 logs 服务日志 启动ZooKeeper 进入Kafka解压缩文件夹的config目录,修改zookeeper.properties配置文件 #t…...
移除链表元素-力扣
题目 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5]示例 2: 输入&…...
HTTP请求拦截器链
文章目录 HTTP请求拦截器链需求定义写一个Controller方法接口写三个http请求拦截器把拦截器加入到配置中,并且配置拦截规则在postman里面发送请求,看下测试结果是否正确 HTTP请求拦截器链 需求定义 我们写一个包含三个HTTP请求拦截器的拦截器链&#x…...
再创佳绩丨达梦数据库一体机荣获2024数字中国创新大赛·信创赛道总决赛一等奖
5月24日,第七届数字中国建设峰会在福州盛大开幕,峰会内容安排包含开幕式、主论坛、分论坛、数字中国创新大赛、现场体验区及成果发布和专业工作会议等。武汉达梦数据库股份有限公司(以下简称达梦数据)受邀参加并在展、会、赛等多个环节深度参与。达梦全栈…...
数据分析之统计学基础
数据分析是现代企业和科研中不可或缺的一部分,而统计学是数据分析的基石。在本篇博客中,我们将介绍统计学的基础知识,涵盖数据类型、描述性统计(集中趋势、离散程度和偏差程度),并通过代码实例加以说明。 …...
Web3 游戏周报(5.19 - 5.25)
【5.19 - 5.25】Web3 游戏行业动态: Arbitrum 已开启 “2 亿枚 ARB 游戏催化剂计划”的提案投票。 STEPN 在官方 X 宣布将推出全新社交健身应用 STEPN GO。 Oasys 正式推出《足球小将》漫改 Web3 游戏《Captain Tsubasa-RIVALS-》。 Gala Games :已销…...
通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求
目录 一、通过el-tree自定义渲染网页版工作目录 1.1、需求介绍 1.2、使用el-tree生成文档目录 1.2.1、官方基础用法 ①效果 ②代码: 1.2.2、自定义文档目录(实现鼠标悬浮显示完整名称、用icon区分文件和文件夹) ①效果(直接效…...
C语言 | Leetcode C语言题解之第101题对称二叉树
题目: 题解: /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ bool isSymmetric(struct TreeNode* root) {if (root NULL) return true;//如果根为空直接…...
TTime:截图翻译/OCR
日常网页翻译Translate Web Pages完全足够,TTime最重要的功能,还是截图翻译,还有个厉害的功能,就是静默OCR,相比之前的分享的识字精灵效率更高。 软件使用 打开软件,点击翻译源设置,建议勾选一…...
【哈希】闭散列的线性探测和开散列的哈希桶解决哈希冲突(C++两种方法模拟实现哈希表)(1)
🎉博主首页: 有趣的中国人 🎉专栏首页: C进阶 🎉其它专栏: C初阶 | Linux | 初阶数据结构 小伙伴们大家好,本片文章将会讲解 哈希函数与哈希 之 闭散列的线性探测解决哈希冲突 的相关内容。 如…...
四川农业大学Java实训项目圆满收官,汇智知了堂引领学子实践创新
近日,四川农业大学与汇智知了堂共同举办的Java实训项目正式迎来了项目汇报阶段。本次实训是汇智知了堂在高等教育领域深化校企合作、推动产教融合的一次重要实践,旨在为广大学子提供一个将理论知识与实际操作相结合的平台。 在实训过程中,汇…...
JavaScript的当前时间设置及Date的运算
作者:私语茶馆 1.场景描述 如下图,在HTML刚加载时,需要将开始时间设置为默认当前时间,结束时间设置为当前时间后7天的时间。手工填写时间时,时间段不超过30天。 这里涉及到两个技术点: 1)Input Date的当前时间设置 2)date的运算 由于是动态修改HTML,所以采用…...
网络安全管理制度
一、总则 目的:本制度旨在保障组织内部网络系统的安全、稳定运行,保护组织的信息资产不受损害,确保业务的连续性和数据的完整性。适用范围:本制度适用于组织内部所有使用网络系统的部门、员工及第三方合作伙伴。 二、网络安全管理…...
零基础,想做一名网络安全工程师,该怎么学习?
相比IT类的其它岗位,网络工程师的学习方向是比较明亮的。想要成为网络工程师,华为认证就是最好的学习方法。而网络工程师的从零开始学习就是从华为认证的初级开始学起,也就是HCIA,也就是从最基本的什么是IP地址、什么是交换机这…...
【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型
【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型 前言 今天来写一个简单的ernie-c#的例子,主要参考了百度智能云的例子,然后自己改了改,学习了ERNIE模型的鉴权方式,数据流的格式和简单的数据解析,实…...
【Unity】Unity项目转抖音小游戏(三)资源分包,抖音云CDN
业务需求,开始接触一下抖音小游戏相关的内容,开发过程中记录一下流程。 使用资源分包可以优化游戏启动速度,是抖音小游戏推荐的一种方式,抖音云也提供存放资源的CDN服务 抖音云官方文档:https://developer.open-douyi…...
会计学论文降AI工具怎么选?财务审计方向高效降重指南
又到了毕业答辩的关键期,不少会计专业的同学都在发愁论文AI率不达标:财务分析部分的数据解读、审计研究的案例推导用AI辅助写完,一检测全是高风险,改了好几遍还是过不了学校的审核。我身边不少师弟师妹踩过工具的坑,要…...
ElevenLabs东北话语音效果翻车?92%开发者忽略的3个声调映射参数,立即校准!
更多请点击: https://codechina.net 第一章:ElevenLabs东北话语音效果翻车现象溯源 近期大量中文开发者在使用 ElevenLabs API 生成东北方言语音时,普遍反馈合成结果严重偏离预期——语调生硬、儿化音缺失、语气词(如“嘎哈”“瞅…...
保姆级教程:在Windows 11上用Mosquitto搭建你的第一个MQTT服务器(含开机自启和用户管理)
Windows 11环境下Mosquitto MQTT服务器全流程部署指南 在物联网项目开发初期,本地搭建MQTT服务器进行原型测试是每个开发者都会经历的环节。作为轻量级的消息传输协议,MQTT凭借其低功耗、低带宽占用和高效的发布/订阅机制,已成为智能家居、工…...
PeaZip:完全免费的跨平台压缩软件,支持200+格式的终极解决方案
PeaZip:完全免费的跨平台压缩软件,支持200格式的终极解决方案 【免费下载链接】PeaZip Free Zip / Unzip software and Rar file extractor. Cross-platform file and archive manager. Features volume spanning, compression, authenticated encryptio…...
从鸟群到AI:Parisi的复本对称破缺,如何成为理解复杂世界的通用钥匙?
无序中的秩序:复本对称破缺如何重塑复杂系统认知 1. 从自旋玻璃到普适范式 1975年的一个寒冷冬日,物理学家Giorgio Parisi在罗马大学的办公室里凝视着杂乱的计算手稿。他当时可能并未意识到,自己即将揭开复杂系统科学最深刻的奥秘之一——复本…...
QGIS连接天地图最新指南:搞定Token和Header,解决加载失败问题
QGIS连接天地图最新指南:搞定Token和Header,解决加载失败问题 天地图作为国内权威的地理信息服务,在QGIS中的集成使用一直是GIS从业者的高频需求。但最近不少用户反馈,按照网上流传的旧教程配置后,天地图服务在QGIS中…...
ARMv8-A架构CAS原子操作原理与优化实践
1. A64指令集的CAS原子操作基础在ARMv8-A架构中,原子操作是并发编程的基础构建块。CAS(Compare and Swap)作为最核心的原子操作之一,其工作原理可以类比为"先验货再付款"的购物过程:首先检查内存中的当前值是…...
如何在Linux上安装Realtek R8125 2.5GbE网卡驱动:完整指南
如何在Linux上安装Realtek R8125 2.5GbE网卡驱动:完整指南 【免费下载链接】realtek-r8125-dkms A DKMS package for easy use of Realtek r8125 driver, which supports 2.5 GbE. 项目地址: https://gitcode.com/gh_mirrors/re/realtek-r8125-dkms 你是否正…...
终极直播输入可视化指南:如何用开源工具展示键盘鼠标操作
终极直播输入可视化指南:如何用开源工具展示键盘鼠标操作 【免费下载链接】input-overlay Show keyboard, gamepad and mouse input on stream 项目地址: https://gitcode.com/gh_mirrors/in/input-overlay 在游戏直播、教学演示或技术分享中,观众…...
终极指南:如何在PC上完美运行PS4游戏?shadPS4模拟器完全解析
终极指南:如何在PC上完美运行PS4游戏?shadPS4模拟器完全解析 【免费下载链接】shadPS4 PS4 emulator for Windows,Linux,MacOS 项目地址: https://gitcode.com/gh_mirrors/shad/shadPS4 想要在个人电脑上重温《血源诅咒》、《如龙》等经典PS4游戏…...
