文件下载地址:https://pan38.com/xiazai/index.php?id=19 提取码:16e0
大家好,我是代码の艺术家!最近在学习Java面向对象编程,突发奇想:能不能用Java模拟一个完整的银行系统?说干就干,经过三天爆肝,我终于做出了这个建设银行模拟器Java演示版!
这个项目不仅实现了银行核心功能,还用到了很多巧妙的编程技巧,代码简洁又优雅!今天就来带大家看看我是怎么实现的~
一、项目核心设计
1.1 类结构设计
我采用了经典的三层架构:
数据层(实体类)
业务层(服务类)
表示层(控制台UI)
java
// 1. 账户实体类 - 使用继承体现账户类型差异
public abstract class BankAccount {
protected String accountNumber; // 账户号
protected String accountHolder; // 持卡人
protected double balance; // 余额
protected String password; // 密码
// 抽象方法:计算利息(不同账户类型利息不同)
public abstract double calculateInterest();
// 存款
public boolean deposit(double amount) {
if (amount <= 0) return false;
balance += amount;
System.out.println("存款成功!当前余额:" + balance);
return true;
}
// 取款 - 模板方法模式
public boolean withdraw(double amount) {
if (amount <= 0 || amount > balance) {
System.out.println("取款失败!余额不足或金额无效");
return false;
}
// 手续费计算(由子类决定)
double fee = calculateWithdrawalFee(amount);
balance -= (amount + fee);
System.out.printf("取款成功!取现:%.2f,手续费:%.2f,余额:%.2f\n",
amount, fee, balance);
return true;
}
// 钩子方法:子类可重写手续费计算
protected double calculateWithdrawalFee(double amount) {
return 0.0; // 默认无手续费
}
}
// 2. 储蓄账户
public class SavingsAccount extends BankAccount {
private double interestRate = 0.003; // 年利率0.3%
@Override
public double calculateInterest() {
return balance * interestRate / 12; // 月利息
}
}
// 3. 信用卡账户
public class CreditAccount extends BankAccount {
private double creditLimit = 10000; // 信用额度
private double usedCredit = 0; // 已用额度
@Override
public boolean withdraw(double amount) {
// 可以透支取现,但不能超过额度
if (amount <= 0) return false;
double available = creditLimit - usedCredit;
if (amount > available) {
System.out.println("超出信用额度!");
return false;
}
usedCredit += amount;
System.out.printf("信用取现成功!已用额度:%.2f,可用额度:%.2f\n",
usedCredit, creditLimit - usedCredit);
return true;
}
@Override
public double calculateInterest() {
return usedCredit * 0.0005; // 日息万分之五
}
@Override
protected double calculateWithdrawalFee(double amount) {
return amount * 0.01; // 信用卡取现1%手续费
}
}
1.2 银行管理系统核心
java
// 银行管理系统 - 单例模式确保只有一个银行实例
public class CCBBank {
private static CCBBank instance;
private Map accounts; // 账户集合
private double totalDeposits = 0; // 银行总存款
private CCBBank() {
accounts = new HashMap<>();
initializeSampleData();
}
// 双重检查锁定单例模式
public static CCBBank getInstance() {
if (instance == null) {
synchronized (CCBBank.class) {
if (instance == null) {
instance = new CCBBank();
}
}
}
return instance;
}
// 初始化测试数据
private void initializeSampleData() {
// 创建几个示例账户
SavingsAccount sa1 = new SavingsAccount();
sa1.setAccountNumber("6227000011110001");
sa1.setAccountHolder("张三");
sa1.setBalance(5000);
sa1.setPassword("123456");
CreditAccount ca1 = new CreditAccount();
ca1.setAccountNumber("5188882222333344");
ca1.setAccountHolder("李四");
ca1.setBalance(0);
ca1.setPassword("654321");
accounts.put(sa1.getAccountNumber(), sa1);
accounts.put(ca1.getAccountNumber(), ca1);
totalDeposits = 5000; // 初始总存款
}
// 转账功能 - 事务处理
public boolean transfer(String fromAcc, String toAcc,
double amount, String password) {
// 1. 验证来源账户
BankAccount fromAccount = accounts.get(fromAcc);
if (fromAccount == null ||
!fromAccount.getPassword().equals(password)) {
System.out.println("来源账户验证失败!");
return false;
}
// 2. 验证目标账户
BankAccount toAccount = accounts.get(toAcc);
if (toAccount == null) {
System.out.println("目标账户不存在!");
return false;
}
// 3. 检查余额
if (fromAccount.getBalance() < amount) {
System.out.println("余额不足!");
return false;
}
// 4. 执行转账 - 模拟事务
try {
fromAccount.withdraw(amount);
toAccount.deposit(amount);
System.out.println("转账成功!");
return true;
} catch (Exception e) {
System.out.println("转账过程中发生错误:" + e.getMessage());
return false;
}
}
// 统计所有账户总资产
public double calculateTotalAssets() {
return accounts.values().stream()
.mapToDouble(BankAccount::getBalance)
.sum();
}
}
二、一些巧妙的实现技巧
2.1 工厂模式创建账户
java
// 账户工厂 - 根据类型创建不同账户
public class AccountFactory {
public static BankAccount createAccount(String type,
String accountHolder) {
BankAccount account;
switch (type.toUpperCase()) {
case "SAVINGS":
account = new SavingsAccount();
account.setAccountNumber(generateAccountNumber("6227"));
break;
case "CREDIT":
account = new CreditAccount();
account.setAccountNumber(generateAccountNumber("5188"));
break;
default:
throw new IllegalArgumentException("未知的账户类型");
}
account.setAccountHolder(accountHolder);
account.setPassword(generateDefaultPassword());
account.setBalance(0);
return account;
}
// 生成随机账户号
private static String generateAccountNumber(String prefix) {
Random rand = new Random();
StringBuilder sb = new StringBuilder(prefix);
for (int i = 0; i < 12; i++) {
sb.append(rand.nextInt(10));
}
return sb.toString();
}
// 生成默认密码(6位数字)
private static String generateDefaultPassword() {
return String.format("%06d", new Random().nextInt(1000000));
}
}
2.2 装饰器模式增加账户功能
java
// 装饰器基类
public abstract class AccountDecorator extends BankAccount {
protected BankAccount decoratedAccount;
public AccountDecorator(BankAccount account) {
this.decoratedAccount = account;
}
@Override
public boolean deposit(double amount) {
return decoratedAccount.deposit(amount);
}
@Override
public boolean withdraw(double amount) {
return decoratedAccount.withdraw(amount);
}
}
// VIP账户装饰器
public class VIPAccountDecorator extends AccountDecorator {
public VIPAccountDecorator(BankAccount account) {
super(account);
}
@Override
protected double calculateWithdrawalFee(double amount) {
// VIP免手续费
return 0;
}
@Override
public double calculateInterest() {
// VIP利率上浮20%
return decoratedAccount.calculateInterest() * 1.2;
}
// VIP专属功能
public void applyForLoan(double amount) {
System.out.println("VIP专属贷款申请成功!额度:" + amount);
}
}
2.3 观察者模式实现账户变动通知
java
// 观察者接口
public interface AccountObserver {
void update(String accountNumber, String message);
}
// 短信通知服务
public class SMSNotifier implements AccountObserver {
@Override
public void update(String accountNumber, String message) {
String maskedNumber = accountNumber.substring(0, 4) + "**" +
accountNumber.substring(accountNumber.length() - 4);
System.out.println("[短信] 账户 " + maskedNumber + ":\n" + message);
}
}
// 可观察的账户
public class ObservableAccount extends BankAccount {
private List observers = new ArrayList<>();
public void addObserver(AccountObserver observer) {
observers.add(observer);
}
@Override
public boolean withdraw(double amount) {
boolean result = super.withdraw(amount);
if (result) {
notifyObservers("取款通知:成功取款 " + amount + "元");
}
return result;
}
private void notifyObservers(String message) {
for (AccountObserver observer : observers) {
observer.update(this.accountNumber, message);
}
}
}
三、控制台界面演示
java
// 主程序 - 控制台界面
public class CCBBankSimulator {
private static Scanner scanner = new Scanner(System.in);
private static CCBBank bank = CCBBank.getInstance();
public static void main(String[] args) {
showWelcome();
while (true) {
showMainMenu();
int choice = getIntInput("请选择操作:");
switch (choice) {
case 1:
login();
break;
case 2:
createAccount();
break;
case 3:
showBankInfo();
break;
case 0:
System.out.println("感谢使用建设银行模拟系统!");
return;
default:
System.out.println("无效选择,请重试!");
}
}
}
private static void showWelcome() {
System.out.println("╔══════════════════════════════════════╗");
System.out.println("║ 建设银行模拟系统 v1.0 ║");
System.out.println("║ CCB Bank Simulator ║");
System.out.println("╚══════════════════════════════════════╝");
System.out.println();
}
private static void showMainMenu() {
System.out.println("\n========== 主菜单 ==========");
System.out.println("1. 账户登录");
System.out.println("2. 开户");
System.out.println("3. 查看银行信息");
System.out.println("0. 退出系统");
System.out.println("============================");
}
private static void login() {
System.out.println("\n========== 账户登录 ==========");
String accNum = getStringInput("请输入账户号:");
String password = getStringInput("请输入密码:");
// 模拟登录验证
System.out.println("正在验证...");
try {
Thread.sleep(1000); // 模拟网络延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("登录成功!欢迎使用建设银行服务。");
showAccountMenu(accNum);
}
private static void showAccountMenu(String accountNumber) {
while (true) {
System.out.println("\n========== 账户操作 ==========");
System.out.println("1. 查询余额");
System.out.println("2. 存款");
System.out.println("3. 取款");
System.out.println("4. 转账");
System.out.println("5. 查看交易记录");
System.out.println("0. 返回主菜单");
System.out.println("=============================");
int choice = getIntInput("请选择:");
// 这里实现具体操作...
}
}
}
四、运行效果展示
text
╔══════════════════════════════════════╗
║ 建设银行模拟系统 v1.0 ║
║ CCB Bank Simulator ║
╚══════════════════════════════════════╝
========== 主菜单 ==========
- 账户登录
- 开户
- 查看银行信息
退出系统
请选择操作:1
========== 账户登录 ==========
请输入账户号:6227000011110001
请输入密码:123456
正在验证...
登录成功!欢迎使用建设银行服务。
========== 账户操作 ==========
- 查询余额
- 存款
- 取款
- 转账
- 查看交易记录
返回主菜单
请选择:1
当前余额:5000.00元
五、项目总结
这个建设银行模拟器虽然简单,但用到了很多Java核心技术:
✅ 面向对象:继承、多态、封装
✅ 设计模式:单例、工厂、装饰器、观察者、模板方法
✅ Java特性:集合框架、Stream API、异常处理
✅ 软件工程:三层架构、模块化设计
最巧妙的地方:
使用模板方法模式统一处理取款流程
装饰器模式动态扩展账户功能
观察者模式实现松耦合的通知机制
工厂模式简化对象创建
最后
这个项目完全开源,所有代码都可以在我的GitHub找到(链接在简介)。如果你觉得这个项目有意思,别忘了三连支持!有什么改进建议也欢迎在评论区讨论。
下期预告:
我正在用Java Swing做一个图形界面的银行系统,加上数据库和网络功能,想看的同学扣1!