🏆本文收录于「滚雪球学SpringBoot」(全网一个名)专栏,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
📝 前言:一次意外的代码相遇
哎呀,说起来也是巧了!前几天在翻阅技术博客的时候,无意中看到了这位"bug菌"大神分享的ATM系统代码(还是大学时代的课后练习)。刚开始我还想着,"不就是个ATM系统嘛,能有多复杂?"结果当我真正深入研究这段代码时,我的想法彻底改变了!🙈
不得不说,这段代码虽然看似简单,但里面蕴含的设计思想和编程技巧,真的让人眼前一亮。从用户体验到安全设计,从异常处理到代码组织结构,每一个细节都透露着作者的用心良苦。今天,我就想跟大家好好聊聊这个ATM系统!一定能让大家学到点东西~
先给大家演示下,启动之后的界面:
🏗️ 整体架构:简洁中的不简洁
🎯 核心组件分析
咦,你有没有注意到这个系统的整体架构?乍一看就是一个主类ATMMainSystem,但仔细研究后发现,作者采用了非常巧妙的设计模式!
private static Scanner scanner = new Scanner(System.in);
private static UserManager userManager = UserManager.getInstance();
private static LoginService loginService = new LoginService();
看到这里,我就忍不住要夸一句了!👏 作者在这里运用了单例模式(UserManager.getInstance()),确保整个系统中只有一个用户管理器实例。这样做的好处是什么呢?
- 内存优化:避免创建多个UserManager实例
- 数据一致性:所有操作都通过同一个实例进行
- 资源控制:统一管理用户数据
嘿,这可不是随便写写的代码啊!每一行都有它存在的意义。💡
🔄 主循环设计的精妙之处
while (true) {
try {
User loginUser = performLogin();
if (loginUser != null) {
handleMainMenu(loginUser);
} else {
if (!askContinue("登录失败,是否继续尝试?")) {
break;
}
}
} catch (Exception e) {
System.out.println("❌ 系统发生异常:" + e.getMessage());
System.out.println("🔄 正在重启系统...");
}
}
哇塞!这个主循环设计真的是太贴心了!😍 你看:
- 持续服务:while(true)保证系统一直运行
- 优雅降级:登录失败后询问是否继续,而不是直接退出
- 异常恢复:catch块捕获异常后重启系统,而不是崩溃
说实话,我见过太多项目,一旦出现异常就直接崩溃退出,用户体验简直糟糕透了!但这里的处理方式,真的是把用户体验考虑到了极致(自夸的感觉真爽)。👍
🔐 登录系统:安全与用户体验的完美平衡
🛡️ 多层验证机制
让我们来看看这个登录系统的设计,简直是教科书级别的示范!
private static User performLogin() {
System.out.println("\n🔑=== 用户登录 ===");
// 输入银行卡号
System.out.print("请输入银行卡号(16位数字):");
String cardNumber = scanner.nextLine().trim();
// 简单的卡号格式验证
if (!isValidCardNumber(cardNumber)) {
System.out.println("❌ 银行卡号格式不正确!请输入16位数字。");
return null;
}
// 检查用户是否存在
User user = userManager.findUserByCardNumber(cardNumber);
if (user == null) {
System.out.println("❌ 该银行卡不存在!请检查卡号是否正确。");
return null;
}
// 密码验证流程
System.out.print("请输入密码:");
String password = scanner.nextLine().trim();
if (loginService.authenticateUser(cardNumber, password, userManager)) {
System.out.println("✅ 登录成功!欢迎您," + user.getUserName() + "!🎉");
return user;
}
return null;
}
哎呀,这个登录流程设计得真的是太周到了!🤩 让我来给大家分析一下这个"三重保险":
- 格式验证:首先检查卡号格式(16位数字)
- 存在验证:检查用户是否在系统中存在
- 身份验证:最后进行密码验证
这样的设计有什么好处呢?我来告诉你:
- 早期拦截:格式错误的输入在第一步就被拦截,节省系统资源
- 友好提示:每一步都有明确的错误提示,用户知道问题出在哪里
- 安全考虑:分步验证可以防止一些常见的攻击手段
🎨 用户体验的贴心设计
你有没有注意到代码中的这些小细节?
String cardNumber = scanner.nextLine().trim();
看到那个.trim()了吗?作者考虑到了用户可能会无意中输入空格的情况!这种细致入微的考虑,真的让人感动啊!😭
还有这个:
System.out.println("✅ 登录成功!欢迎您," + user.getUserName() + "!🎉");
登录成功后不仅有emoji表情,还会显示用户姓名,这种个性化的问候真的太暖心了!💕
🏠 主菜单系统:功能丰富yet简洁明了
📋 菜单设计的艺术
private static void displayMainMenu(User user) {
System.out.println("\n🏦========== ATM主菜单 ==========");
System.out.println("👤 当前用户:" + user.getUserName());
System.out.println("💳 银行卡号:" + maskCardNumber(user.getCardNumber()));
System.out.println("────────────────────────────────");
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("================================");
}
哇!这个菜单设计真的是太用心了吧!🌟 你们看:
- 视觉层次:用分割线清晰划分区域
- 信息展示:显示当前用户和脱敏的银行卡号
- emoji装饰:让枯燥的文字界面变得生动有趣
- 数字编号:用emoji数字让选项更直观
特别是这个银行卡号脱敏处理:
private static String maskCardNumber(String cardNumber) {
if (cardNumber == null || cardNumber.length() != 16) {
return cardNumber;
}
return cardNumber.substring(0, 4) + " **** **** " + cardNumber.substring(12);
}
6222 **** **** 5678 这样的显示方式,既保护了用户隐私,又让用户能够确认是自己的卡号。这种安全意识,真的值得我们学习!🔒
🎯 Switch语句的优雅处理
switch (choice) {
case "1":
// 查询余额
System.out.println("\n💰=== 余额查询 ===");
atmService.queryBalance();
pressEnterToContinue();
break;
case "2":
// 存款操作
handleDeposit(atmService);
break;
// ... 其他case
default:
System.out.println("❌ 无效的选择,请重新输入!");
break;
}
这个switch语句的处理真的很棒!每个功能都独立封装成方法,代码结构清晰,维护起来也方便。而且,pressEnterToContinue()这个方法的使用,让用户有时间查看操作结果,用户体验满分!💯
💰 存取款功能:细节决定成败
🏧 取款功能的人性化设计
让我们来看看这个取款功能,真的是太贴心了!
private static void handleWithdraw(ATMService atmService) {
System.out.println("\n💸=== 取款操作 ===");
// 显示快捷金额选项
System.out.println("💡 快捷取款金额:");
System.out.println("1. ¥100 2. ¥200 3. ¥500");
System.out.println("4. ¥1000 5. ¥2000 6. 其他金额");
System.out.print("请选择取款方式:");
String choice = scanner.nextLine().trim();
double amount = 0;
try {
switch (choice) {
case "1": amount = 100; break;
case "2": amount = 200; break;
case "3": amount = 500; break;
case "4": amount = 1000; break;
case "5": amount = 2000; break;
case "6":
System.out.print("请输入取款金额:¥");
amount = Double.parseDouble(scanner.nextLine().trim());
break;
default:
System.out.println("❌ 无效的选择!");
return;
}
atmService.withdraw(amount);
} catch (NumberFormatException e) {
System.out.println("❌ 输入的金额格式不正确!请输入数字。");
}
pressEnterToContinue();
}
哎呀妈呀!这个设计真的是太聪明了!😱 你看:
- 快捷选项:提供常用金额的快捷选择
- 自定义金额:也支持用户输入任意金额
- 异常处理:捕获数字格式异常,防止程序崩溃
- 用户引导:清晰的提示信息
这种设计考虑到了不同用户的需求:急着取钱的用户可以快速选择常用金额,有特殊需求的用户也可以自定义输入。真的是兼顾了效率和灵活性!🎯
💳 存款功能的简洁优雅
private static void handleDeposit(ATMService atmService) {
System.out.println("\n💰=== 存款操作 ===");
try {
System.out.print("请输入存款金额:¥");
String amountStr = scanner.nextLine().trim();
double amount = Double.parseDouble(amountStr);
atmService.deposit(amount);
} catch (NumberFormatException e) {
System.out.println("❌ 输入的金额格式不正确!请输入数字。");
}
pressEnterToContinue();
}
相比取款功能,存款功能就显得简洁很多,但该有的异常处理一个都不少!这种根据业务需求调整复杂度的做法,真的很专业!👨💻
🔑 密码修改:安全性的极致体现
说到安全性,这个密码修改功能真的是让我刮目相看!
private static void handleChangePassword(User user) {
System.out.println("\n🔑=== 修改密码 ===");
// 验证原密码
System.out.print("请输入原密码:");
String oldPassword = scanner.nextLine().trim();
if (!user.verifyPassword(oldPassword)) {
System.out.println("❌ 原密码不正确!");
pressEnterToContinue();
return;
}
// 输入新密码
System.out.print("请输入新密码(6位数字):");
String newPassword = scanner.nextLine().trim();
if (!isValidPassword(newPassword)) {
System.out.println("❌ 密码格式不正确!请输入6位数字。");
pressEnterToContinue();
return;
}
// 确认新密码
System.out.print("请再次输入新密码:");
String confirmPassword = scanner.nextLine().trim();
if (!newPassword.equals(confirmPassword)) {
System.out.println("❌ 两次输入的密码不一致!");
pressEnterToContinue();
return;
}
System.out.println("✅ 密码修改成功!请重新登录。");
System.out.println("💡 提示:实际系统中,这里会调用数据库更新操作");
pressEnterToContinue();
}
哇塞!这个密码修改流程简直是教科书级别的安全设计!🛡️ 让我来数数有多少道安全防线:
- 原密码验证:确保是本人操作
- 新密码格式检查:确保密码符合规则
- 二次确认:防止输入错误
- 强制重新登录:密码修改后需要重新验证身份
每一步都有详细的错误提示,每一个环节都考虑到了安全性。这种严谨的态度,真的让人敬佩!🙏
🔍 输入验证的精妙设计
private static boolean isValidCardNumber(String cardNumber) {
return cardNumber != null &&
cardNumber.matches("\\d{16}"); // 16位数字
}
private static boolean isValidPassword(String password) {
return password != null &&
password.matches("\\d{6}"); // 6位数字
}
这两个验证方法看似简单,其实考虑得很周到:
- 空值检查:防止NullPointerException
- 正则表达式:精确匹配格式要求
- 简洁明了:代码可读性很强
特别是\\d{16}和\\d{6}这种正则表达式的使用,既严格又简洁,真的很棒!✨
🎨 用户体验设计:让技术有温度
😊 Emoji的巧妙运用
不得不说,这个系统最让我印象深刻的就是emoji的使用!🌈
System.out.println("🎊========================================🎊");
System.out.println("🏦 欢迎使用智能ATM系统! 🏦");
System.out.println("🎊========================================🎊");
你看这个欢迎界面,瞬间就让枯燥的命令行界面变得生动有趣!这种细节的处理,真的能让用户感受到开发者的用心。💕
还有各种功能的emoji标识:
- 🔑 登录
- 💰 余额查询
- 💸 取款
- 🔑 密码修改
- 👥 用户列表
每个emoji都选得恰到好处,既有装饰作用,又有功能指示意义。这种设计思维,真的值得我们学习!🤓
🎯 交互体验的贴心设计
private static void pressEnterToContinue() {
System.out.println("\n📱 按回车键继续...");
scanner.nextLine();
}
这个小方法真的太贴心了!让用户有时间查看操作结果,而不是匆匆忙忙地跳转到下一个界面。这种"停顿"的设计,在用户体验中真的很重要!⏸️
private static boolean askContinue(String message) {
System.out.print(message + "(y/n):");
String response = scanner.nextLine().trim().toLowerCase();
return response.equals("y") || response.equals("yes") || response.equals("是");
}
这个方法更厉害!不仅支持英文的"y"和"yes",还支持中文的"是"。这种国际化的考虑,真的很专业!🌍
🚀 代码架构的深度思考
🏗️ 分层架构的体现
虽然这只是一个相对简单的ATM系统,但作者在架构设计上的思考真的很深入:
- 表示层:ATMMainSystem负责用户交互
- 业务层:ATMService处理业务逻辑
- 服务层:LoginService处理登录验证
- 数据层:UserManager管理用户数据
这种分层的思想,即使在简单的项目中也得到了很好的体现。每一层都有自己的职责,耦合度很低,扩展性很强!🏢
🔄 责任链模式的应用
在登录验证过程中,我们可以看到一种类似责任链模式的设计思想:
// 1. 格式验证
if (!isValidCardNumber(cardNumber)) {
return null;
}
// 2. 存在验证
User user = userManager.findUserByCardNumber(cardNumber);
if (user == null) {
return null;
}
// 3. 身份验证
if (loginService.authenticateUser(cardNumber, password, userManager)) {
return user;
}
每一步验证都是独立的,失败了就直接返回,成功了才进入下一步。这种设计既提高了效率,又让代码逻辑更清晰!⚡
🛠️ 实际开发中的最佳实践
📝 代码注释的艺术
让我们来看看作者的注释风格:
/**
* 🔐 用户登录流程
* 这里实现了完整的登录验证逻辑,包括错误处理哦!
*/
private static User performLogin() {
// ...
}
这种注释风格真的很棒!不仅有emoji让注释更生动,还简洁明了地说明了方法的功能。这种写注释的方式,既实用又有趣!📖
🎯 异常处理的最佳实践
try {
double amount = Double.parseDouble(amountStr);
atmService.deposit(amount);
} catch (NumberFormatException e) {
System.out.println("❌ 输入的金额格式不正确!请输入数字。");
}
这种异常处理方式真的很专业:
- 精确捕获:只捕获可能出现的NumberFormatException
- 友好提示:给用户明确的错误信息
- 程序继续:不会因为异常而崩溃
这种处理方式,在实际项目中真的很重要!🎪
🔮 代码优化与扩展建议(自我审视)
其实,读完我大学时代写的代码,还是有些代码写的不够优雅,不知道你们有没有发现...
💡 我的一些小建议
看完这个代码后,我也有一些小想法想跟大家分享:
1. 配置化管理
// 可以考虑将这些硬编码的值提取到配置文件中
private static final int CARD_NUMBER_LENGTH = 16;
private static final int PASSWORD_LENGTH = 6;
private static final String[] QUICK_AMOUNTS = {"100", "200", "500", "1000", "2000"};
2. 日志系统的引入
// 建议引入日志框架,比如SLF4J
private static final Logger logger = LoggerFactory.getLogger(ATMMainSystem.class);
public static void main(String[] args) {
logger.info("ATM系统启动");
// ...
}
3. 输入重试机制
// 可以为密码输入添加重试限制
private static final int MAX_PASSWORD_ATTEMPTS = 3;
当然啦,这些只是我个人的一些想法,原代码已经很优秀了!🌟
🚀 扩展性思考
如果要扩展这个系统,我觉得可以考虑以下几个方向:
- 转账功能:用户之间的资金转移
- 交易记录:查看历史交易信息
- 多语言支持:国际化处理
- 数据持久化:连接真正的数据库
- 网络通信:支持远程ATM服务
每一个扩展都需要在保持现有代码结构的基础上进行,这也体现了良好架构设计的重要性!🏗️
🎓 学习心得与感悟
💭 从这个项目中学到了什么
说实话,研究完这个ATM系统后,我的收获真的很大!主要有以下几点:
1. 细节决定成败
从.trim()的使用到emoji的装饰,从异常处理到用户提示,每一个细节都体现了作者的用心。这让我明白,好的代码不仅要功能正确,更要考虑用户体验!💖
2. 安全意识很重要
银行卡号脱敏、多重密码验证、异常恢复机制,这些安全设计在日常开发中往往容易被忽略,但却是至关重要的!🛡️
3. 代码可读性的价值
清晰的方法命名、合理的代码组织、友好的注释风格,这些都让代码变得易于理解和维护。好的代码就应该像一本好书一样,让人读起来赏心悦目!📚
4. 用户体验无处不在
即使是命令行界面,也可以通过emoji、合理的交互流程、友好的提示信息来提升用户体验。技术不仅要解决问题,更要让人感到温暖!🌈
🎯 对初学者的建议
如果你也是Java初学者,我建议你:
- 多看优秀代码:像这个ATM系统一样的代码,真的值得反复研究
- 注重细节:不要只关注功能实现,也要考虑用户体验和安全性
- 勤于实践:自己动手写代码,遇到问题及时解决
- 保持学习:技术在不断发展,我们也要持续学习新知识
记住,编程不仅是技术活,更是一门艺术!🎨
🎉 结语:技术与人文的完美结合
写到这里,我真的被这个ATM系统深深震撼了!一个看似简单的项目,却蕴含着如此丰富的设计思想和编程技巧。从技术架构到用户体验,从安全设计到代码优雅,每一个方面都体现了作者的专业水准和人文关怀。
这让我想起了一句话:"细节之中见真章,平凡之中见不凡。"这个ATM系统就是最好的例证!它告诉我们,好的代码不仅要解决问题,更要让人感受到温度;不仅要功能强大,更要简洁优雅。
希望通过我的这篇分析,能让更多的朋友认识到代码之美,感受到编程的魅力。也希望我们都能向这位"bug菌"大神学习,写出更加优秀、更有温度的代码!
最后,感谢这位作者的分享,让我们有机会学习到如此优秀的代码!如果你也对这个项目有什么想法或建议,欢迎在评论区一起讨论哦!🤝
好了,今天的分享就到这里啦!我要去继续研究代码了,咱们下次见!👋
📣 关于我
我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云多年度十佳博主&最具价值贡献奖,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。
-End-