以银行卡取钱的流程为例的状态模式的 java 的 demo

好的,下面我们将用状态模式来实现一个模拟从银行卡取钱的流程。

假设我们有以下几个状态:

  1. 输入卡
  2. 输入密码
  3. 选择操作
  4. 取款
  5. 取卡

我们通过状态模式来实现这些状态之间的切换。

状态接口

首先,我们定义一个状态接口 ATMState

// ATMState.java
public interface ATMState {void insertCard(ATMContext context);void enterPin(ATMContext context, String pin);void selectOperation(ATMContext context, String operation);void withdrawCash(ATMContext context, double amount);void ejectCard(ATMContext context);
}

具体状态类

接下来,我们定义几个具体的状态类,分别实现 ATMState 接口。

InsertCardState.java

public class InsertCardState implements ATMState {@Overridepublic void insertCard(ATMContext context) {System.out.println("Card inserted. Please enter your PIN.");context.setState(new EnterPinState());}@Overridepublic void enterPin(ATMContext context, String pin) {System.out.println("Please insert card first.");}@Overridepublic void selectOperation(ATMContext context, String operation) {System.out.println("Please insert card first.");}@Overridepublic void withdrawCash(ATMContext context, double amount) {System.out.println("Please insert card first.");}@Overridepublic void ejectCard(ATMContext context) {System.out.println("No card to eject.");}
}

EnterPinState.java

public class EnterPinState implements ATMState {@Overridepublic void insertCard(ATMContext context) {System.out.println("Card already inserted. Please enter your PIN.");}@Overridepublic void enterPin(ATMContext context, String pin) {if ("1234".equals(pin)) { // 假设 1234 是正确的 PINSystem.out.println("PIN accepted. Please select operation.");context.setState(new SelectOperationState());} else {System.out.println("Incorrect PIN. Please try again.");}}@Overridepublic void selectOperation(ATMContext context, String operation) {System.out.println("Please enter PIN first.");}@Overridepublic void withdrawCash(ATMContext context, double amount) {System.out.println("Please enter PIN first.");}@Overridepublic void ejectCard(ATMContext context) {System.out.println("Card ejected.");context.setState(new InsertCardState());}
}

SelectOperationState.java

public class SelectOperationState implements ATMState {@Overridepublic void insertCard(ATMContext context) {System.out.println("Card already inserted.");}@Overridepublic void enterPin(ATMContext context, String pin) {System.out.println("PIN already entered.");}@Overridepublic void selectOperation(ATMContext context, String operation) {if ("withdraw".equalsIgnoreCase(operation)) {System.out.println("Operation selected: Withdraw. Please enter amount.");context.setState(new WithdrawCashState());} else {System.out.println("Invalid operation. Please select again.");}}@Overridepublic void withdrawCash(ATMContext context, double amount) {System.out.println("Please select operation first.");}@Overridepublic void ejectCard(ATMContext context) {System.out.println("Card ejected.");context.setState(new InsertCardState());}
}

WithdrawCashState.java

public class WithdrawCashState implements ATMState {@Overridepublic void insertCard(ATMContext context) {System.out.println("Card already inserted.");}@Overridepublic void enterPin(ATMContext context, String pin) {System.out.println("PIN already entered.");}@Overridepublic void selectOperation(ATMContext context, String operation) {System.out.println("Operation already selected.");}@Overridepublic void withdrawCash(ATMContext context, double amount) {if (amount > 0) {System.out.println("Withdrawing " + amount + " dollars. Please take your cash.");context.setState(new EjectCardState());} else {System.out.println("Invalid amount. Please enter again.");}}@Overridepublic void ejectCard(ATMContext context) {System.out.println("Please withdraw cash first.");}
}

EjectCardState.java

public class EjectCardState implements ATMState {@Overridepublic void insertCard(ATMContext context) {System.out.println("Please take your card first.");}@Overridepublic void enterPin(ATMContext context, String pin) {System.out.println("Please take your card first.");}@Overridepublic void selectOperation(ATMContext context, String operation) {System.out.println("Please take your card first.");}@Overridepublic void withdrawCash(ATMContext context, double amount) {System.out.println("Please take your card first.");}@Overridepublic void ejectCard(ATMContext context) {System.out.println("Card ejected.");context.setState(new InsertCardState());}
}

上下文类

最后,我们定义一个上下文类 ATMContext,它持有当前状态并在方法调用时委托给当前状态处理:

// ATMContext.java
public class ATMContext {private ATMState state;public ATMContext() {state = new InsertCardState();}public void setState(ATMState state) {this.state = state;}public void insertCard() {state.insertCard(this);}public void enterPin(String pin) {state.enterPin(this, pin);}public void selectOperation(String operation) {state.selectOperation(this, operation);}public void withdrawCash(double amount) {state.withdrawCash(this, amount);}public void ejectCard() {state.ejectCard(this);}public static void main(String[] args) {ATMContext atm = new ATMContext();atm.insertCard();           // 插卡atm.enterPin("1234");       // 输入正确的密码atm.selectOperation("withdraw"); // 选择取款操作atm.withdrawCash(100);      // 取款 100 美元atm.ejectCard();            // 弹出卡片}
}

运行结果

当我们运行 ATMContext 类中的 main 方法时,会看到以下输出:

Card inserted. Please enter your PIN.
PIN accepted. Please select operation.
Operation selected: Withdraw. Please enter amount.
Withdrawing 100.0 dollars. Please take your cash.
Card ejected.

代码说明

  1. 状态接口

    • ATMState 接口定义了在取钱过程中可能出现的各种操作方法。
  2. 具体状态类

    • InsertCardStateEnterPinStateSelectOperationStateWithdrawCashStateEjectCardState 类分别实现了 ATMState 接口,并在每个状态下实现相应的行为和状态转换逻辑。
  3. 上下文类

    • ATMContext 类持有一个 ATMState 类型的成员变量 state,用于表示当前状态。
    • ATMContext 的各个方法调用当前状态的相应方法,并根据具体状态类中的实现进行状态转换。

结论

通过使用状态模式,我们将取钱过程中的各个状态和行为封装在独立的状态类中,避免了复杂的条件判断语句,使得代码更加简洁和易于维护。每个状态类只关注自身的行为和状态转换逻辑,这使得系统更具扩展性和可读性。

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

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

相关文章

【python+selenium的web自动化】—— 控制浏览器

前言: 需本教程以Edge做测试,且谷歌、火狐等浏览器的逻辑都一样需要使用 selenium 模块操作 Edge 浏览器。 一、先通过pip install 模块 把selenium模块安装了,可以加一个中国源提升速度。pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple二、需要下载Edg…

Python自动化之控制浏览器

前言: 需本教程以Edge做测试,且谷歌、火狐等浏览器的逻辑都一样需要使用 selenium 模块操作 Edge 浏览器。 一、先通过pip install 模块 把selenium模块安装了,可以加一个中国源提升速度。pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple二、需要下载Edg…

设计模式-设计原则与设计模式总结

设计原则,是设计模式的基础。在实际开发中,并不是一定要求所有代码都遵循设计原则,我们需要综合考虑人力、时间、成本、质量,不是可以追求完美,要在设当的场景遵循合适的设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。 设计模式(Design Pattern)是前…

mirai Bot初始化配置

RT其实本来我的bot已经因为自己手贱登陆qq nt直接报废了,但是论坛里有佬提供了新的协议库,那这不赶紧复活bot都对不起这个新的协议库。 本文写于2024年7月4日19:20:21,可能随着时间久远而无法实现功能。由于存在下载障碍,所以这里也搞了个存档,本帖中的相关标星*资源无法下…

量化曲线的平滑程度

思路 1. 对原始数据一阶求导,得到一阶导数数组。 2. 对一阶导数数组求标准差。导数的标准差提供了导数值的波动性,标准差越小,曲线越平滑。 平滑曲线import numpy as np import matplotlib.pyplot as plt from matplotlib import font_manager fname="/usr/local/pytho…

Android常见错误

错误1 A problem occurred configuring root project ����ʶ��. > Could not resolve all files for configuration :classpath.> Could not resolve com.android.tools.build:gradle:8.4.0.Required by:project : > com.android.application:com.android.appli…

MyBatis中的Where标签:提升你的SQL查询效率

哈喽,大家好,我是木头左!理解MyBatis的Where标签 MyBatis是一款优秀的持久层框架,它提供了许多强大的标签来帮助编写更优雅、高效的SQL语句。其中,<where>标签是使用频率极高的一个,它能够自动处理查询条件,使得的SQL语句更加简洁和高效。在这篇文章中,将深入探讨…

Java中的JSON神器,如何轻松玩转复杂数据结构

哈喽,大家好,我是木头左!一、揭秘JSON世界的基石 在Java的世界中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于文本,易于阅读和编写,同时也易于机器解析和生成。JSON在日常开发中的应用非常广泛,无论是前后端的数据交互,还是配置文件的读取,…

《Python 第三方模块包安装指南》

在 Python 编程中,第三方模块包极大地丰富了其功能,让我们能够更高效地完成各种任务。下面将为您详细介绍如何安装 Python 的第三方模块包。 一、使用 pip 命令安装 pip 是 Python 的包管理工具,大多数情况下,我们可以通过以下命令来安装第三方模块包:pip install 模块包名…

巴图自动化Modbus转PN网关模块连智能仪表与PLC通讯

通过巴图自动化Modbus转Profinet协议网关模块,实现PLC对仪表设备的远程监控和数据传输,提高生产效率和运行稳定性。巴图自动化Modbus转Profinet协议转换BT-MDPN100网关模块的主要功能是实现Modbus协议和Profinet协议之间的转换和通信。Modbus 转 Profinet协议网关模块集成了M…

一文搞懂到底什么是 AQS

日常开发中,我们经常使用锁或者其他同步器来控制并发,那么它们的基础框架是什么呢?如何实现的同步功能呢?本文将详细用白话讲解构建锁和同步器的基础框架--AQS,并根据源码分析其原理。前言 日常开发中,我们经常使用锁或者其他同步器来控制并发,那么它们的基础框架是什么…

flutter状态管理 provider使用

provider是flutter官方推荐的状态管理插件,是基于InheritedWidget实现的。 下面我们来讲一个provider的使用方法。 1.在pubspec.yaml文件中添加 provider: ^6.1.2 开发文档:https://pub-web.flutter-io.cn/packages/provider 可以查看使用方法和最新版本号。 添加完成后…

企业数字化转型:顶层规划方法

随着数字化时代的到来,发生了以数字化、智能化为典型特征的新一轮科技革命,各行各业利用互联网、大数据、云计算、人工智能、区块链技术对传统产业进行全方位、全链条改造,实施“上云用数赋智”行动,全面推进各行业数字化转型。数字经济的大门已然开启,数字经济顶层战略规…

Nuxt3 的生命周期和钩子函数(十)

摘要:本文详细介绍了Nuxt3框架中的五个webpack钩子函数:webpack:configResolved用于在webpack配置解析后读取和修改配置;webpack:compile在编译开始前调用,可修改编译选项;webpack:compiled在编译完成后调用,可处理编译结果;webpack:change在开发模式下文件变化时触发,…

Jenkins汉化

1、Jenkins版本:版本2.426.3) Manage Jenkins->选择Plugins->切换到Availabled plugin->搜索local,然后选中安装,如下图所示 2、安装完成后重启Jenkins,汉化完成。如下图所示 像个小学生一样努力学习

模拟集成电路设计系列博客——9.1 比较器

模拟集成电路设计 9.1 比较器 比较器可能是继放大器之后第二常用的电路元件,比较器用于判断一个信号是否大于或小于零,或者比较一个信号是否大于另一个。如我们之前的章节所见,比较器在ADC中非常常用。在其他的应用中也经常出现比较器,例如数据传输,开关电源稳压器等等。 …

prufer序列

prufer序列用途: 将带标号的树用唯一的整数序列表示出来,证明凯莱公式。构造方法:每次选择一个编号最小的叶结点并删掉它,然后在序列中记录下它连接到的那个结点。重复\(n-2\)次后就只剩下两个结点,算法结束。 举个栗子(本图来自baoziwu2,侵删)显然可以有一个用堆做的方法,…

【冷启动#2】实用的springboot tutorial入门demo

跟着官方文档熟悉一遍创建spring工程的步骤 https://spring.io/guides/gs/spring-boot https://juejin.cn/post/7077958723829760008 demo简介 整个demo的预期目标是: 管理一堆玩家的数据,数据库使用的是现成的我们虚拟机上安装的MySQL 项目结构参考 主要工作:创建并熟悉spr…

CentOS8部署zerotier异地组网

本文介绍了在CentOS 8系统上部署ZeroTier以实现异地组网的方法,包括安装、配置、加入网络、开启IP转发和设置路由表等步骤,并提出进一步实现公网无缝组网的展望。CentOS8部署zerotier异地组网 CentOS8部署zerotier异地组网 一、前言 本文在此前研究部署FRP进行内网穿透,但FR…

《DNK210使用指南 -CanMV版 V1.0》第九章 打印输出实验

第九章 打印输出实验 1)实验平台:正点原子DNK210开发板 2)章节摘自【正点原子】DNK210使用指南 - CanMV版 V1.0 3)购买链接:https://detail.tmall.com/item.htm?&id=782801398750 4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DN…