当前位置: 首页 > news >正文

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种设计模式&#xff08;一&#xff09;- 创建型模式》 《深入了解JAVA中的23种设计模式&#xff08;二&#xff09;- 结构型模式》 《深入了解JAVA中的23种设计模式&#xff08;三&#xff09;- 行为型模式&#xff08;上&#xff09;》…...

微信小程序【WXML】

wxml wei xin markup language 类似于html 文档 数据绑定 小程序中使用{{}} 来进行数据绑定到模板中&#xff0c;如: wxml中的动态数据全部来自js中的data 简单绑定 //wxml <view> {{text }}</view>// index.js Page({data: {text: hello world}, })属性绑定…...

基于python实现的深度学习的车牌识别系统

基于python实现的深度学习的车牌识别系统 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 登录页面 在车牌识别系统当中肯定是有登录的。怎么说呢&#xff0c;登录页面其实还是和最初的设…...

SQL试题使得每个学生 按照姓名的字⺟顺序依次排列 在对应的⼤洲下⾯

学⽣地理信息报告 学校有来⾃亚洲、欧洲和美洲的学⽣。 表countries 数据如下&#xff1a; namecontinentJaneAmericaPascalEuropeXiAsiaJackAmerica 1、编写解决⽅案实现对⼤洲&#xff08;continent&#xff09;列的 透视表 操作&#xff0c;使得每个学生 按照姓名的字⺟顺…...

kafka3.6.1版本学习

kafka目录结构 bin linux系统下可执行脚本文件 bin/windows windows系统下可执行脚本文件 config 配置文件 libs 依赖类库 licenses 许可信息 site-docs 文档 logs 服务日志 启动ZooKeeper 进入Kafka解压缩文件夹的config目录&#xff0c;修改zookeeper.properties配置文件 #t…...

移除链表元素-力扣

题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&…...

HTTP请求拦截器链

文章目录 HTTP请求拦截器链需求定义写一个Controller方法接口写三个http请求拦截器把拦截器加入到配置中&#xff0c;并且配置拦截规则在postman里面发送请求&#xff0c;看下测试结果是否正确 HTTP请求拦截器链 需求定义 我们写一个包含三个HTTP请求拦截器的拦截器链&#x…...

再创佳绩丨达梦数据库一体机荣获2024数字中国创新大赛·信创赛道总决赛一等奖

5月24日&#xff0c;第七届数字中国建设峰会在福州盛大开幕&#xff0c;峰会内容安排包含开幕式、主论坛、分论坛、数字中国创新大赛、现场体验区及成果发布和专业工作会议等。武汉达梦数据库股份有限公司(以下简称达梦数据)受邀参加并在展、会、赛等多个环节深度参与。达梦全栈…...

数据分析之统计学基础

数据分析是现代企业和科研中不可或缺的一部分&#xff0c;而统计学是数据分析的基石。在本篇博客中&#xff0c;我们将介绍统计学的基础知识&#xff0c;涵盖数据类型、描述性统计&#xff08;集中趋势、离散程度和偏差程度&#xff09;&#xff0c;并通过代码实例加以说明。 …...

Web3 游戏周报(5.19 - 5.25)

【5.19 - 5.25】Web3 游戏行业动态&#xff1a; Arbitrum 已开启 “2 亿枚 ARB 游戏催化剂计划”的提案投票。 STEPN 在官方 X 宣布将推出全新社交健身应用 STEPN GO。 Oasys 正式推出《足球小将》漫改 Web3 游戏《Captain Tsubasa-RIVALS-》。 Gala Games &#xff1a;已销…...

通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求

目录 一、通过el-tree自定义渲染网页版工作目录 1.1、需求介绍 1.2、使用el-tree生成文档目录 1.2.1、官方基础用法 ①效果 ②代码&#xff1a; 1.2.2、自定义文档目录&#xff08;实现鼠标悬浮显示完整名称、用icon区分文件和文件夹&#xff09; ①效果&#xff08;直接效…...

C语言 | Leetcode C语言题解之第101题对称二叉树

题目&#xff1a; 题解&#xff1a; /*** 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完全足够&#xff0c;TTime最重要的功能&#xff0c;还是截图翻译&#xff0c;还有个厉害的功能&#xff0c;就是静默OCR&#xff0c;相比之前的分享的识字精灵效率更高。 软件使用 打开软件&#xff0c;点击翻译源设置&#xff0c;建议勾选一…...

【哈希】闭散列的线性探测和开散列的哈希桶解决哈希冲突(C++两种方法模拟实现哈希表)(1)

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; C进阶 &#x1f389;其它专栏&#xff1a; C初阶 | Linux | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解 哈希函数与哈希 之 闭散列的线性探测解决哈希冲突 的相关内容。 如…...

四川农业大学Java实训项目圆满收官,汇智知了堂引领学子实践创新

近日&#xff0c;四川农业大学与汇智知了堂共同举办的Java实训项目正式迎来了项目汇报阶段。本次实训是汇智知了堂在高等教育领域深化校企合作、推动产教融合的一次重要实践&#xff0c;旨在为广大学子提供一个将理论知识与实际操作相结合的平台。 在实训过程中&#xff0c;汇…...

JavaScript的当前时间设置及Date的运算

作者:私语茶馆 1.场景描述 如下图,在HTML刚加载时,需要将开始时间设置为默认当前时间,结束时间设置为当前时间后7天的时间。手工填写时间时,时间段不超过30天。 这里涉及到两个技术点: 1)Input Date的当前时间设置 2)date的运算 由于是动态修改HTML,所以采用…...

网络安全管理制度

一、总则 目的&#xff1a;本制度旨在保障组织内部网络系统的安全、稳定运行&#xff0c;保护组织的信息资产不受损害&#xff0c;确保业务的连续性和数据的完整性。适用范围&#xff1a;本制度适用于组织内部所有使用网络系统的部门、员工及第三方合作伙伴。 二、网络安全管理…...

零基础,想做一名网络安全工程师,该怎么学习?

​ 相比IT类的其它岗位&#xff0c;网络工程师的学习方向是比较明亮的。想要成为网络工程师&#xff0c;华为认证就是最好的学习方法。而网络工程师的从零开始学习就是从华为认证的初级开始学起&#xff0c;也就是HCIA&#xff0c;也就是从最基本的什么是IP地址、什么是交换机这…...

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型 前言 今天来写一个简单的ernie-c#的例子&#xff0c;主要参考了百度智能云的例子&#xff0c;然后自己改了改&#xff0c;学习了ERNIE模型的鉴权方式&#xff0c;数据流的格式和简单的数据解析&#xff0c;实…...

【Unity】Unity项目转抖音小游戏(三)资源分包,抖音云CDN

业务需求&#xff0c;开始接触一下抖音小游戏相关的内容&#xff0c;开发过程中记录一下流程。 使用资源分包可以优化游戏启动速度&#xff0c;是抖音小游戏推荐的一种方式&#xff0c;抖音云也提供存放资源的CDN服务 抖音云官方文档&#xff1a;https://developer.open-douyi…...

软件测试之压力测试总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是压力测试软件测试中&#xff1a;压力测试&#xff08;Stress Test&#xff09;&#xff0c;也称为强度测试、负载测试。压力测试是模拟实际应用的软硬件…...

从编译到定制:WinSCP全流程开发指南

从编译到定制&#xff1a;WinSCP全流程开发指南 【免费下载链接】winscp WinSCP is a popular free file manager for Windows supporting SFTP, FTP, FTPS, SCP, S3, WebDAV and local-to-local file transfers. A powerful tool to enhance your productivity with a user-fr…...

R语言实战:利用compareGroups包高效生成临床研究三线表(Table1)

1. 为什么临床研究离不开Table1三线表 在医学论文和临床研究报告中&#xff0c;Table1三线表几乎是标配。我第一次投稿时&#xff0c;审稿人直接指出"缺少规范的基线特征表"&#xff0c;这才意识到这个表格的重要性。Table1的核心作用是展示研究人群的基线特征&#…...

【Typst源文件】Typst 标题层级与样式定制

1. 标题层级&#xff1a;等号 的使用 Typst 使用等号 来定义标题&#xff0c;等号的数量决定标题层级。理论上没有层级限制&#xff0c;可以根据文档结构无限嵌套。一级标题二级标题三级标题四级标题五级标题六级标题七级标题八级标题使用示例IntroductionBackgroundPrevious…...

深入RK3588 NPU架构:从NVDLA远亲到CNN加速器的设计取舍与性能真相

RK3588 NPU架构深度解构&#xff1a;CNN加速器的设计哲学与性能边界 当一块指甲盖大小的芯片宣称能提供6 TOPS的AI算力时&#xff0c;我们不禁要问&#xff1a;这数字背后隐藏着怎样的工程智慧与妥协&#xff1f;RK3588的NPU模块正引发这样的思考——它既非纯粹的学术创新&…...

什么是哈希算法?(大白话+原理+应用,一次讲透)

文章目录一、一句话定义二、用生活例子秒懂对应到代码里&#xff1a;三、哈希算法的核心特性&#xff08;面试必背&#xff09;四、为什么 HashSet.contains() 是 O(1)&#xff1f;&#xff08;结合哈希原理&#xff09;五、哈希算法的常见应用&#xff08;你日常都在用&#x…...

忍者像素绘卷:天界画坊Java面试题精讲:AI绘画服务的高并发设计

忍者像素绘卷&#xff1a;天界画坊Java面试题精讲&#xff1a;AI绘画服务的高并发设计 1. 高并发AI绘画服务的挑战与价值 在数字艺术创作领域&#xff0c;AI绘画服务正经历爆发式增长。以"忍者像素绘卷&#xff1a;天界画坊"为例&#xff0c;这款融合传统忍者文化与…...

跨平台监控整合指南:如何用GB28181协议让海康/大华NVR对接第三方平台?

跨平台监控整合实战&#xff1a;GB28181协议下海康/大华NVR与第三方平台对接全解析 在商业综合体、智慧园区等大型监控项目中&#xff0c;不同品牌设备的混合部署已成为常态。海康威视、大华等主流厂商的NVR设备如何通过GB28181协议与第三方监控平台实现无缝对接&#xff1f;本…...

2025_NIPS_Prompt Tuning Transformers for Data Memorization

文章核心总结与翻译 一、主要内容 文章聚焦提示调优(Prompt Tuning)在Transformer模型数据记忆能力上的表现,通过理论分析与实证研究,明确提示调优的记忆机制与关键特性: 理论层面:推导了精确记忆有限数据集所需的提示长度上界,证明常数规模Transformer可通过长度为O~…...

3个步骤突破微信小程序渲染瓶颈:pixi-miniprogram的WebGL性能革新实践

3个步骤突破微信小程序渲染瓶颈&#xff1a;pixi-miniprogram的WebGL性能革新实践 【免费下载链接】pixi-miniprogram 一个可运行于微信小程序的PIXI引擎&#xff0c;通过模拟window环境&#xff0c;有些功能小程序无法模拟&#xff0c;就直接修改了PIXI引擎代码&#xff0c;最…...