首页 > 编程语言 >以银行卡取钱的流程为例的状态模式的 java 的 demo

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

时间:2024-07-04 20:21:05浏览次数:1  
标签:java 为例 demo void System ATMContext context println public

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

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

  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 {
    @Override
    public void insertCard(ATMContext context) {
        System.out.println("Card inserted. Please enter your PIN.");
        context.setState(new EnterPinState());
    }

    @Override
    public void enterPin(ATMContext context, String pin) {
        System.out.println("Please insert card first.");
    }

    @Override
    public void selectOperation(ATMContext context, String operation) {
        System.out.println("Please insert card first.");
    }

    @Override
    public void withdrawCash(ATMContext context, double amount) {
        System.out.println("Please insert card first.");
    }

    @Override
    public void ejectCard(ATMContext context) {
        System.out.println("No card to eject.");
    }
}

EnterPinState.java

public class EnterPinState implements ATMState {
    @Override
    public void insertCard(ATMContext context) {
        System.out.println("Card already inserted. Please enter your PIN.");
    }

    @Override
    public void enterPin(ATMContext context, String pin) {
        if ("1234".equals(pin)) { // 假设 1234 是正确的 PIN
            System.out.println("PIN accepted. Please select operation.");
            context.setState(new SelectOperationState());
        } else {
            System.out.println("Incorrect PIN. Please try again.");
        }
    }

    @Override
    public void selectOperation(ATMContext context, String operation) {
        System.out.println("Please enter PIN first.");
    }

    @Override
    public void withdrawCash(ATMContext context, double amount) {
        System.out.println("Please enter PIN first.");
    }

    @Override
    public void ejectCard(ATMContext context) {
        System.out.println("Card ejected.");
        context.setState(new InsertCardState());
    }
}

SelectOperationState.java

public class SelectOperationState implements ATMState {
    @Override
    public void insertCard(ATMContext context) {
        System.out.println("Card already inserted.");
    }

    @Override
    public void enterPin(ATMContext context, String pin) {
        System.out.println("PIN already entered.");
    }

    @Override
    public 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.");
        }
    }

    @Override
    public void withdrawCash(ATMContext context, double amount) {
        System.out.println("Please select operation first.");
    }

    @Override
    public void ejectCard(ATMContext context) {
        System.out.println("Card ejected.");
        context.setState(new InsertCardState());
    }
}

WithdrawCashState.java

public class WithdrawCashState implements ATMState {
    @Override
    public void insertCard(ATMContext context) {
        System.out.println("Card already inserted.");
    }

    @Override
    public void enterPin(ATMContext context, String pin) {
        System.out.println("PIN already entered.");
    }

    @Override
    public void selectOperation(ATMContext context, String operation) {
        System.out.println("Operation already selected.");
    }

    @Override
    public 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.");
        }
    }

    @Override
    public void ejectCard(ATMContext context) {
        System.out.println("Please withdraw cash first.");
    }
}

EjectCardState.java

public class EjectCardState implements ATMState {
    @Override
    public void insertCard(ATMContext context) {
        System.out.println("Please take your card first.");
    }

    @Override
    public void enterPin(ATMContext context, String pin) {
        System.out.println("Please take your card first.");
    }

    @Override
    public void selectOperation(ATMContext context, String operation) {
        System.out.println("Please take your card first.");
    }

    @Override
    public void withdrawCash(ATMContext context, double amount) {
        System.out.println("Please take your card first.");
    }

    @Override
    public 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 的各个方法调用当前状态的相应方法,并根据具体状态类中的实现进行状态转换。

结论

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

标签:java,为例,demo,void,System,ATMContext,context,println,public
From: https://www.cnblogs.com/gongchengship/p/18284601

相关文章

  • JavaScript中的异步模式
    JavaScript中的异步模式JavaScript语言的执行环境是“单线程(singlethread)”,就是指一次只能完成一个任务。如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任务,以此类推。这种模式的好处是实现起来比较简单,执行环境相对单纯,坏处是只要有一个任务耗时很长,后面的任务......
  • Java 如何连接 ElasticSearch
    在Java中连接Elasticsearch可以使用Elasticsearch提供的官方Java客户端。Elasticsearch官方提供的Java客户端有多种,其中最常用的是RestHighLevelClient。下面是使用RestHighLevelClient连接Elasticsearch的详细步骤。1.添加依赖首先,在你的项目中添加Elasticsearch客户端的依赖......
  • Java SSH 客户端 如何删除 linux 机器上的 文件
    在Java中,可以使用SSH客户端库如JSch(JavaSecureChannel)来连接到远程Linux机器并执行命令,包括删除文件。下面是一个使用JSch库的示例,展示如何通过SSH删除远程Linux机器上的文件。步骤:添加JSch库:确保您的项目包含JSch库。如果您使用的是Maven,可以在pom.xml......
  • Java28-反射
    目录概述学习反射到底学什么获取字节码文件对象的三种方式字节码文件和字节码文件对象获取构造方法获取构造方法并创建对象获取成员变量获取成员变量并获取值和修改值获取成员方法获取成员方法并运行练习泛型擦除修改字符串的内容反射和配置文件结合动态获取利......
  • Java 中Json中既有对象又有数组的参数 如何转化成对象
    1.示例一:解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象在Java中处理JSON数据,尤其是当JSON结构中既包含对象又包含数组时,常用的库有org.json、Gson和Jackson。这里我将以Gson为例来展示如何解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象。首先......
  • Java for循环倒序输出
    1.实现一个for循环的倒序输出在Java中,要实现一个for循环的倒序输出,通常我们会使用数组或集合(如ArrayList)作为数据源,然后通过倒序遍历这个数组或集合来实现。下面,我将给出一个详细的示例,使用数组作为数据源,通过for循环倒序输出数组中的元素。这个示例不仅可以直接运行,而且具有一定......
  • 【如何判断动作事件是否由按钮引发】基于Java-GUI
    在刚刚写GUI的时候,我突然想到怎样去判断某一个事件源是由哪一个监听器响应的,所以我来整理后编写这次总结。(❁´◡`❁)❤当然首先得需要有一个按钮对象♥JButtonbt=newJButton();//创建按钮对象╰(*°▽°*)╯♥这里存在俩种情况♥如果按钮创建和判断方法在一......
  • Java中的JSON神器,如何轻松玩转复杂数据结构
    哈喽,大家好,我是木头左!一、揭秘JSON世界的基石在Java的世界中,JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它基于文本,易于阅读和编写,同时也易于机器解析和生成。JSON在日常开发中的应用非常广泛,无论是前后端的数据交互,还是配置文件的读取,都离不开JSON的身影。那......
  • Java基础:线程的三种创建方式
    一、继承Thread类定义一个类继承线程类Thread重写run()方法创建线程对象调用线程对象的start()方法创建线程Thread类的常用APIsetName(Stringname):给线程取名字getName():获取线程的名字publicstaticThreadcurrentThread():获取当前线程对象,这个代码在哪个线程中就获......
  • CenterOS7安装java
    CenterOS7安装java#进入安装目录cd/usr/local/soft/java#wget下载java8#直接进入官网选择相应的版本进行下载,然后把下载链接复制下来就可以下载了#不时间的下载链接不一样wgethttp://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/......