重构WoniuATM并完善其功能(一)
通过对面向对象编程基础知识的学习,我们应该对Java编程有了更进一步的理解,同时也能够更好地将其应用于WoniuATM模拟系统的开发中。本实验将重点带领大家一直来对WoniuATM进行重构,优化,并更多地融入面向对象编程思想,将系统的核心功能全部实现。
通过对面向对象编程基础知识的学习,我们应该对Java编程有了更进一步的理解,同时也能够更好地将其应用于WoniuATM模拟系统的开发中。本实验将重点带领大家一直来对WoniuATM进行重构,优化,并更多地融入面向对象编程思想,将系统的核心功能全部实现。
实验目的
1.灵活运用面向对象编程思想对WoniuATM的代码结构进行模块化设计。
2.熟练使用Java编程语言的特性,提升WoniuATM代码的可读性,可维护性。
3.熟练运用Java进行编程,找到适合自己的编程方法,梳理清楚业务逻辑与代码实现之间的突破口,找到编程的成就感或挫败感,完成程序设计的深度学习体验。
实验流程
1.为第二个版本的重构新建一个包“com.woniuxy.atm.two”来单独管理,避免与前面的代码重复。此处需要注意和是,如果在第一个版本中我们直接复制代码过来,会导致直接将对应的类从“com.woniuxy.atm.one”包中导入,这会导致类混乱,这一点需要特别注意。
2.根据核心功能规划类
通过对需求的确认,我们可以规划4个类来分别完成对应的功能:
(1) 主界面: MainUI,主要负责登录注册界面和操作菜单子界面的绘制。
(2) 用户管理类:UserManager,主要负责用户的注册,登录,资料维护等操作。
(3) 用户数据类:UserData,主要定义一个纯数据类,用于保存用户信息。
(4) 账户操作类:AccountOperation,主要负责用户的余额查询,取款,转账,存钱等操作。
3.为三个核心类定义public接口方法
MainUI类:
package com.woniuxy.atm.two; public class MainUI { // 主方法,程序由此开始运行 public static void main(String[] args) { MainUI ui = new MainUI(); // 定义当前类的变量(实例)ui ui.mainMenu(); } // 绘制主操作菜单(登录前由主方法直接调用) public void mainMenu() { } // 绘制子操作菜单(登录成功后调用) public void subMenu() { } } |
UserManager类:
package com.woniuxy.atm.two; public class UserManager { // 实现登录功能 public void login() { } // 实现注册功能 public void register() { } } |
AccountManager类:
package com.woniuxy.atm.two; public class AccountManager { // 查询余额 public void query() { } // 转账 public void transfer() { } // 取款 public void withdraw() { } // 存款 public void deposit() { } } |
UserData类:利用失血模型定义的数据类,请参考后续实现代码。
为什么我们需要通过这样的步骤来实现代码呢?除了可以上我们的MainUI代码可以实现正常的调用而不会报错以外,针对上述代码结构,还需要补充以下几点:
(1) 首先,在实现代码功能逻辑之前,先保证代码有一个清晰简洁的结构。
(2) 其次,这些方法都必须要设置为public的公开方法,因为这些方法必然会被其它类调用。
(3) 再者,这些方法是不是设置好以后就不用调整了呢,比如方法的返回值类型,参数等?不是,这只是实现了代码的基本框架,具体实现代码功能的时候,我们还会作进一步的调整和优化。
(4) 最后,我们要在这些类当中添加其它方法可以吗?当然可以,为了更好地辅助完成公开接口的方法实现,我们可以定义更多其它方法来协助实现。但是,如无特殊需要,可以将这些方法定义为private,在本类中私有。这样,就不会出现太多公开的接口方法而在其它类当中又用不上的情况,让代码更加简洁。
4.实现MainUI
由于MainUI只负责主菜单和子菜单两个菜单的绘制,而菜单选择后具体调用哪个方法实现功能由用户管理类和账户管理类来完成,所以我们只需要定义简单的菜单调用和选项即可。所以,在MainUI类中,除了实现main方法外,我们只需要实现mainMenu和subMenu两个方法即可,代码如下:
package com.woniuxy.atm.two; import java.util.Scanner;
public class MainUI { UserManager um = new UserManager(); AccountManager am = new AccountManager();
public static void main(String[] args) { MainUI ui = new MainUI(); // 定义当前类的变量(实例)ui ui.mainMenu(); // 调用当前类的方法mainMenu() }
// 绘制主操作菜单(登录前由主方法直接调用) public void mainMenu() { System.out.println("=====欢迎使用蜗牛ATM无限制存取款系统======="); System.out.println("===请输入你的选项,1:登录 2:注册 3:退出 ==="); System.out.println("=================================="); Scanner sc = new Scanner(System.in); String option = sc.next(); switch (option) { case "1": this.um.login(); // this: 代表本类的实例(只适用于非静态方法之间的调用) break; case "2": this.um.register(); break; case "3": System.exit(0); // 退出当前程序 break; default: System.out.println("你输入的选项错误,请重新输入。 "); this.mainMenu(); // 当输入错误的时候,通过递归调用自己,重新提示输入 break; } }
// 绘制子操作菜单(登录成功后调用) public void subMenu() { System.out.println("====================请输入你的选 项:==============="); System.out.println("==1:查询余额 2:转账 3:取款 4:存款 5:返回主菜单 6:退出=="); System.out.println("=============================================="); Scanner sc = new Scanner(System.in); String option = sc.next(); switch (option) { case "1": this.am.query(); // 调用查询余额的方法 break; case "2": this.am.transfer(); // 调用转账的方法 break; case "3": this.am.withdraw(); // 调用取款的方法 break; case "4": this.am.deposit(); // 调用存款的方法 break; case "5": this.mainMenu(); // 返回主菜单 break; case "6": System.exit(0); // 退出 break; default: System.out.println("你输入的选项错误,请重新输入。 "); this.subMenu(); // 当输入错误的时候,通过递归调用自己,重新提示输入 break; } } } |
在上述代码中,由于我们已经在UserManager和AccountManager两个类中定义了接口方法,所以代码是不会出错,可以正常运行的。还希望大家慢慢体会这种类型的开发过程,后面的测试开发中我们依然会用到这种小技巧。
注:因为本节内容较长,所以特拆解为了两部分,以上是基础知识,下周将分享第二部分 关于“实现UserData数据类"、“实现UserManager类”、“实现AccountManager类”的知识,以及思考练习。
小伙伴们敬请期待哟~