12.状态模式

文章目录

  • 状态模式
  • 总结


状态模式

介绍

状态模式它允许一个对象在其内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要目的是将对象的状态封装成不同的类,并将对象的行为委托给当前状态。

组成

  1. Context(环境): 维护一个对具体状态的引用,维护一个状态对象,并将与状态相关的操作委托给当前状态对象。
  2. State(状态): 定义一个接口或抽象类,封装了与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态): 实现了State接口,每个具体状态类都提供了在状态改变时处理的具体行为。

结构图

在这里插入图片描述

场景

假设我们有一个订单处理系统,订单在不同的状态下可以执行不同的操作,比如创建、支付、发货、完成等

版本1.0

// 不使用状态模式的订单类
class OrderWithoutState {private String state;public OrderWithoutState() {// 初始状态为创建状态state = "Created";}public void setState(String newState) {this.state = newState;}public void processOrder() {if ("Created".equals(state)) {System.out.println("Order created, waiting for payment");// 可以执行创建订单后的其他逻辑} else if ("Paid".equals(state)) {System.out.println("Payment received, preparing for shipment");// 可以执行支付后的其他逻辑} else if ("Shipped".equals(state)) {System.out.println("Order shipped, waiting for confirmation");// 可以执行发货后的其他逻辑} else if ("Completed".equals(state)) {System.out.println("Order completed, thank you for your purchase");// 可以执行订单完成后的其他逻辑}}
}
// 客户端
public class WithoutStatePatternExample {public static void main(String[] args) {OrderWithoutState order = new OrderWithoutState();// 创建订单order.processOrder();// 支付订单order.setState("Paid");order.processOrder();// 发货order.setState("Shipped");order.processOrder();// 完成订单order.setState("Completed");order.processOrder();}
}

问题

上面的实现中,订单类包含一个表示状态的字符串属性,通过条件语句判断当前订单状态,并执行相应的逻辑。这种实现方式会导致代码中出现大量的条件判断,难以维护,并且不符合开闭原则,当需要添加新的订单状态时,需要修改原有的代码。

使用状态模式版本

// 状态接口
interface OrderState {void processOrder(OrderContext context);
}
// 具体状态1:创建状态
class CreatedState implements OrderState {@Overridepublic void processOrder(OrderContext context) {System.out.println("Order created, waiting for payment");// 可以执行创建订单后的其他逻辑}
}// 具体状态2:支付状态
class PaidState implements OrderState {@Overridepublic void processOrder(OrderContext context) {System.out.println("Payment received, preparing for shipment");// 可以执行支付后的其他逻辑}
}// 具体状态3:发货状态
class ShippedState implements OrderState {@Overridepublic void processOrder(OrderContext context) {System.out.println("Order shipped, waiting for confirmation");// 可以执行发货后的其他逻辑}
}// 具体状态4:完成状态
class CompletedState implements OrderState {@Overridepublic void processOrder(OrderContext context) {System.out.println("Order completed, thank you for your purchase");// 可以执行订单完成后的其他逻辑}
}
// 环境类:订单上下文
class OrderContext {private OrderState currentState;public OrderContext() {// 初始状态为创建状态currentState = new CreatedState();}public void setState(OrderState state) {this.currentState = state;}public void processOrder() {currentState.processOrder(this);}
}
// 客户端
public class StatePatternExample {public static void main(String[] args) {OrderContext order = new OrderContext();// 创建订单order.processOrder();// 支付订单order.setState(new PaidState());order.processOrder();// 发货order.setState(new ShippedState());order.processOrder();// 完成订单order.setState(new CompletedState());order.processOrder();}
}

在这个版本的实现中,我们定义了订单的不同状态,并使用状态模式来处理订单状态的变化。每个具体状态类都实现了 OrderState 接口,提供了处理订单的具体逻辑。OrderContext 类是环境类,维护了当前订单的状态,并通过委托给当前状态对象来执行相应的操作。


总结

优点

  1. 封装性好: 将每个状态封装到一个类中,使得每个状态的实现对其他状态都是独立的,更容易添加新的状态。

  2. 可扩展性好: 容易添加新的状态类,符合开闭原则。

  3. 避免了使用大量的条件语句: 状态模式将不同状态的逻辑分离,避免了使用大量的条件语句来判断当前状态。

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

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

相关文章

开启Android学习之旅-1

最近在学习《第一行代码 Android》,两天看书把所有代码都敲了一遍。由于之前没有接触过 Kotlin,导致了囫囵吞枣,跟着书会敲,离开就忘了。Android 大佬开发的各种框架、控件好像大部分都用了 Kotlin。看他们的源码,理解…

UnityShader——01Shader和渲染管线

Shader和渲染管线 什么是Shader Shader中文翻译为着色器,是一种较为短小的程序片段,用于告诉图形硬件如何计算和输出图像,过去由汇编语言编写,现在也可以使用高级语言进行编写。 即,Shader是一种可编程图形管线的算法…

第五篇:MySQL常见数据类型

MySQL中的数据类型有很多,主要分为三类:数值类型、字符串类型、日期时间类型 三个表格都在此网盘中,需要者可移步自取,如果觉得有帮助希望点个赞~ MySQL常见数据类型表 数值类型 (注:decimal类型举例,如1…

从左值和右值的角度分析a++和++a

摘自牛客上的一个题目: int a5,则 (a)的值是? 答案是会编译报错。 原因: a返回的是右值(rvalue),而我们不能对一个右值进行自增操作。所以(a)会报错。 怎么理解呢? (a)返回的是a在1之前的值,这个值是一个…

system V——进程间通信

上一篇博客中我介绍了system V进程间通信中的内存共享,但是其中还有两 种通信方式:消息队列、和信号量,接下来我将简单介绍一下,消息队列和 信号量以及操作系统是如何看待system V进程间通信的。1. 消息队列 a. 大致介绍 消息队…

Python:解析数组二分查找算法bisect

简介:bisect模块提供对维护一个已排序列表而无须在每次插入后对该列表重排序的支持。对于具有大量条目需要大量比较运算的长列表,这改进了原来的线性搜索或频繁重排序。之所以被命名为 bisect 是因为它使用了基本的二分算法来完成任务。 不同于其他搜索特…

MOCO动量编码

参考,推荐阅读 李沐论文精读系列三:MoCo、对比学习综述(MoCov1/v2/v3、SimCLR v1/v2、DINO等)_moco 对比学习-CSDN博客 背景 1. MOCO CVPR 2020 2. 对比学习:无监督学习的一种,重点学习同类实例中的共同…

【教3妹学编程-算法题】使数组异或和等于 K 的最少操作次数

3妹:2哥,新年好鸭~ 2哥 : 新年好,3妹这么早啊 3妹:是啊,新年第一天要起早,这样就可以起早一整年 2哥 :得,我还不了解你,每天晒到日上三竿 3妹:嘿嘿嘿嘿,一年是…

分享88个表单按钮JS特效,总有一款适合您

分享88个表单按钮JS特效,总有一款适合您 88个表单按钮JS特效下载链接:https://pan.baidu.com/s/1v-qcl8bv2kxZ8a98Xo9UAg?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,…

Python解决SSL不可用问题

参考:https://blog.csdn.net/weixin_44894162/article/details/126342591 一、问题描述: 报错概述: WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. ## 警告:pip配…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(4)深度学习和机器学习

关于深度学习和机器学习,出来包含关系之外,还有如上总结的知识点。 分别从特征处理、学习方法、数据依赖、硬件依赖等4个方面,进行了总结。 从特征处理上看:深度学习从数据中习得高级特征,并自行创建新的特征。这比普…

并发容器+并发队列【ConcurentHashMap、CopyOnWriteArrayList、阻塞队列、ArrayBlockingQueue】

并发容器 什么是并发容器?同步容器:并发容器: ConcurrentHashMap结构图JDK1.7结构图JDK1.8结构图 CopyOnWriteArrayList实现原理 并发队列阻塞队列ArrayBlockingQueue 转自极客时间 什么是并发容器? 在JUC包中,有一大部分是关于并发容器的,如Concurr…