首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

手把手教你寫 Java 版 ATM 系統:從領域模型到控制台交互完整實作

     編輯:Java 相關知識

ATM 系統是 Java 初學者練習 OOP、異常處理、集合框架、IO 流的經典題目。本文提供一個結構清晰、可直接運行的完整實作,涵蓋賬戶實體、業務邏輯、控制台 UI 與主流程。

領域模型:Account

package cn.atm;

public class Account {
    private final String number;
    private final String name;
    private String password; // 允許修改密碼
    private double balance;

    public Account(String number, String name, String password, double balance) {
        this.number = number;
        this.name = name;
        this.password = password;
        this.balance = balance;
    }

    // Getters / Setters 省略
    public boolean verifyPassword(String pwd) { return this.password.equals(pwd); }
    public void deposit(double amt) { if (amt > 0) balance += amt; }
    public boolean withdraw(double amt) { if (amt > 0 && amt <= balance) { balance -= amt; return true; } return false; }
    public double getBalance() { return balance; }
}

業務核心:ATMService

package cn.atm;

import java.io.*;
import java.util.*;

public class ATMService {
    private final Map accounts = new HashMap<>();
    private Account currentAccount;

    public ATMService() {
        // 預設測試賬戶
        accounts.put("0000", new Account("0000", "Test User", "0000", 2000.0));
    }

    public boolean login(String cardNo, String pwd) {
        Account acc = accounts.get(cardNo);
        if (acc != null && acc.verifyPassword(pwd)) {
            currentAccount = acc;
            return true;
        }
        return false;
    }

    public void deposit(double amt) { currentAccount.deposit(amt); }
    public boolean withdraw(double amt) { return currentAccount.withdraw(amt); }
    public double queryBalance() { return currentAccount.getBalance(); }
    public void showInfo() {
        System.out.printf("賬號: %s | 姓名: %s | 餘額: %.2f%n",
                currentAccount.getNumber(), currentAccount.getName(), currentAccount.getBalance());
    }
}

控制台交互層:ATMConsole

package cn.atm;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ATMConsole {
    private final ATMService service = new ATMService();
    private final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    public void start() {
        System.out.println("=== 歡迎使用 Java ATM 系統 ===");
        if (!loginLoop()) return;
        mainMenuLoop();
    }

    private boolean loginLoop() {
        for (int i = 0; i < 3; i++) {
            try {
                System.out.print("請輸入卡號: ");
                String card = br.readLine().trim();
                System.out.print("請輸入密碼: ");
                String pwd = br.readLine().trim();
                if (service.login(card, pwd)) {
                    System.out.println("登入成功!");
                    return true;
                }
                System.out.println("卡號或密碼錯誤,剩餘嘗試 " + (2 - i) + " 次");
            } catch (IOException e) {
                System.err.println("輸入異常: " + e.getMessage());
            }
        }
        System.out.println("嘗試次數過多,系統鎖定。");
        return false;
    }

    private void mainMenuLoop() {
        while (true) {
            printMenu();
            try {
                String input = br.readLine().trim();
                switch (input) {
                    case "1" -> withdrawFlow();
                    case "2" -> service.showInfo();
                    case "3" -> depositFlow();
                    case "4" -> { System.out.println("感謝使用,再見!"); return; }
                    default -> System.out.println("無效選項,請輸入 1-4");
                }
            } catch (IOException e) {
                System.err.println("輸入異常: " + e.getMessage());
            }
        }
    }

    private void printMenu() {
        System.out.println("\n=== 主選單 ===");
        System.out.println("1. 取款");
        System.out.println("2. 查詢");
        System.out.println("3. 存款");
        System.out.println("4. 退出");
        System.out.print("請選擇 (1-4): ");
    }

    private void withdrawFlow() throws IOException {
        System.out.print("請輸入取款金額: ");
        double amt = Double.parseDouble(br.readLine().trim());
        if (service.withdraw(amt)) {
            System.out.printf("取款成功,餘額: %.2f%n", service.queryBalance());
        } else {
            System.out.println("餘額不足或金額無效");
        }
    }

    private void depositFlow() throws IOException {
        System.out.print("請輸入存款金額: ");
        double amt = Double.parseDouble(br.readLine().trim());
        service.deposit(amt);
        System.out.printf("存款成功,餘額: %.2f%n", service.queryBalance());
    }

    public static void main(String[] args) {
        new ATMConsole().start();
    }
}

運行示例

=== 歡迎使用 Java ATM 系統 ===
請輸入卡號: 0000
請輸入密碼: 0000
登入成功!

=== 主選單 ===
1. 取款
2. 查詢
3. 存款
4. 退出
請選擇 (1-4): 2
賬號: 0000 | 姓名: Test User | 餘額: 2000.00

進階擴展方向

  • 持久化:引入 SQLite / H2 / MyBatis 將賬戶落盤
  • 交易記錄:新增 Transaction 實體,記錄時間、類型、金額、餘額
  • 並發安全:ReentrantLock 守護單賬戶操作,或資料庫樂觀鎖
  • 安全加固:密碼 BCrypt 加密、輸入驗證防注入、敏感操作二次確認
  • 介面升級:Swing/JavaFX/Web (Spring Boot + Vue) 重構 UI

結語

這個迷你 ATM 雖小,卻涵蓋了「實體-服務-表現」分層、異常處理、集合操作、IO 交互等核心技能。建議初學者先跑通、再重構、最後擴展,一步步養成工程化思維。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved