当前位置: 首页 > 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);  }  
}  

  设计模式不是公式,没必要去死记硬背每一种模式,更重要的是了解它的抽象思想,以及应用设计模式怎么更好地解决问题,可以达成什么效果。理论虽多,但是我们要把它掌握的话,对于我们的实际开发来说会解决不少的问题。

http://www.lryc.cn/news/355943.html

相关文章:

  • 微信小程序【WXML】
  • 基于python实现的深度学习的车牌识别系统
  • SQL试题使得每个学生 按照姓名的字⺟顺序依次排列 在对应的⼤洲下⾯
  • kafka3.6.1版本学习
  • 移除链表元素-力扣
  • HTTP请求拦截器链
  • 再创佳绩丨达梦数据库一体机荣获2024数字中国创新大赛·信创赛道总决赛一等奖
  • 数据分析之统计学基础
  • Web3 游戏周报(5.19 - 5.25)
  • 通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求
  • C语言 | Leetcode C语言题解之第101题对称二叉树
  • TTime:截图翻译/OCR
  • 【哈希】闭散列的线性探测和开散列的哈希桶解决哈希冲突(C++两种方法模拟实现哈希表)(1)
  • 四川农业大学Java实训项目圆满收官,汇智知了堂引领学子实践创新
  • JavaScript的当前时间设置及Date的运算
  • 网络安全管理制度
  • 零基础,想做一名网络安全工程师,该怎么学习?
  • 【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型
  • 【Unity】Unity项目转抖音小游戏(三)资源分包,抖音云CDN
  • SQLite查询优化
  • UE4编辑器End键Actor贴近地面
  • 2024儿科常用心理评估量表汇总,附详细操作步骤与评定标准
  • Python 脚本化 Git 操作:简单、高效、无压力
  • 手搓顺序表(C语言)
  • 一文搞懂oracle事务提交以及脏数据落盘的原则
  • OceanBase:列存储
  • Rust:WIndows 环境下交叉编译 Linux 平台程序
  • 从零学爬虫:使用比如说说解析网页结构
  • C#数据类型变量、常量
  • Java高级面试问题及答案