目录
前言
项目规划(第二周)
具体实现
用户大类
AccountOperations接口
UserOperations接口
Operations类(实现类)
Account类
User类
Area类 (父类)
货币大类
Money类(抽象类)
操作界面
LoginInterface类
MainInterface类
RegistrationInterface类
三个界面的txt文档设计
后言
前言
上一周对ATM机模拟系统做了项目需求分析(Java实现ATM机模拟系统(week1)-CSDN博客),这周来做部分的实现。
项目规划(第二周)
-
完成操作页面展示
-
完成用户的登录。注册等用户基本操作
-
学习I/O,要求用户数据必须持久化(也可使用jdbc+mysql)
-
做好类的封装,自定义异常处理
具体实现
用户大类
AccountOperations接口
该接口主要定义了对帐户进行的操作方法,包括以下
- 创建账户
- 登录账户
- 退出账户
- 保存账户信息
- 调出账户信息
package Account.Operations.Method;import Account.Account;
import Area.Area;import java.io.FileNotFoundException;public interface AccountOperations {public Account createAccount( Area area); // 创建账户public Account landAccount( String accountNumber, String cipher); // 登录账户public void logOut( Account account) throws FileNotFoundException; // 退出账户public void saveAccountInformation( Account account);public Account retrieveAccountInformation( String accountNumber, String cipher);
}
UserOperations接口
该接口主要定义了用户执行的操作方法,目前包括以下
- 存款
- 取款
- 查询余额
- 修改密码
package Account.Operations.Method;import Account.Account;
import Currency.Money;public interface UserOperations {public void saveMoney( Money money, Account account); // 存钱public void withdraw( Money money, Account account); // 取钱public boolean checkBalance(Account account); // 查询余额public void changeCipher( Account account); // 修改密码
}
Operations类(实现类)
该类用于实现以上两个接口的方法
package Account.Operations;import Account.Account;
import Account.Operations.Method.AccountOperations;
import Account.Operations.Method.UserOperations;
import Area.Area;
import Currency.Money;
import OperationInterface.LoginInterface;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.util.Scanner;public class Operations implements AccountOperations, UserOperations {Operations operations = new Operations();LoginInterface loginInterface = new LoginInterface();@Overridepublic Account createAccount( Area area) {Scanner s = new Scanner(System.in);// 给出账号System.out.println("输入本人身份证号码:");String id = s.next();// 给出手机号System.out.println("输入本人手机号:");String mobileNumber = s.next();StringBuilder ac = new StringBuilder();ac.append(area.obtainNumber());SecureRandom num = new SecureRandom();for( int i = 0; i < 11; i++) {int t = num.nextInt(10);ac.append(t);}String accountNumber = ac.toString();// 输入密码String cipher =s.next();// 创建一个账号,并且初始化账号, 并且返回一个账号return new Account( accountNumber, cipher, 0.0, 0.0, 0, id, mobileNumber);}@Overridepublic Account landAccount( String accountNumber, String cipher) {// 直接调用retrieveAccountInformation()方法调出相应账户Account account = retrieveAccountInformation( accountNumber, cipher);if( account == null ) {System.out.println("输入账号密码有误,请重新输入!!!");// 返回登录操作继续输入账号和密码Scanner s = new Scanner(System.in);// 如果有什么其他操作, 如 创建账号、修改密码操作, 加这里/* ········· */// 利用递归函数重复输入,直到能匹配到账号为止account = landAccount( s.next(), s.next());}return account;}@Overridepublic void logOut( Account account) throws FileNotFoundException {// 将目前的账号清空, 重复利用account = null;System.out.println("账号退出成功!!!");// 退出账号后的后续操作写这里/* ······ *///返回登录界面loginInterface.loginInterface();//operations.landAccount() ; //}@Overridepublic void saveAccountInformation( Account account) {// 为这个账户创建一个文本文档,存放账户信息String address = "E:\\Account\\" + account.getAccountNumber() + ".txt";File save = new File(address);// 如果文件已经存在,直接覆盖掉之前的信息保存if( save.exists() ) {try (FileOutputStream fileOut = new FileOutputStream(address) ) {ObjectOutputStream oos = new ObjectOutputStream(fileOut);oos.writeObject(account);oos.close();fileOut.close();System.out.println("账户信息保存成功");} catch (IOException e) {throw new RuntimeException("账户信息保存失败");}}// 如果文件不存在,者创建一个新文件存放账户信息else {try {if( save.createNewFile() ) {try (FileOutputStream fileOut = new FileOutputStream(address) ) {ObjectOutputStream oos = new ObjectOutputStream(fileOut);oos.writeObject(account);oos.close();fileOut.close();System.out.println("账户信息保存成功");} catch (IOException e) {throw new RuntimeException("账户信息保存失败");}}} catch (IOException e) {throw new RuntimeException(e);}}}@Overridepublic Account retrieveAccountInformation( String accountNumber, String cipher) {String address = "E:\\Account";// 读取指定路径目录File dictionary = new File(address);// 将该目录中的文件读入到list中File[] list = dictionary.listFiles();Account result = null;if( list != null ) {// 通过循环遍历目录中的文件,进行逐个查找for( File t : list) {Path find = Path.of(t.getAbsolutePath());String content = null;try {content = new String(Files.readAllBytes(find));} catch (IOException e) {throw new RuntimeException(e);}if( content.contains(accountNumber) && content.contains(cipher) ) {// 将目标文件信息读取到一个Account对象中try (FileInputStream in = new FileInputStream(address + "\\" + t.getName())) {ObjectInputStream oos = new ObjectInputStream(in);try {result = (Account) oos.readObject();} catch (ClassNotFoundException e) {throw new ClassCastException("读取用户信息失败!!!");}in.close();oos.close();} catch (IOException e) {throw new RuntimeException(e);}break;}}}else {System.out.println("目录为空!!!");}return result;}@Overridepublic void saveMoney(Money money, Account account) {Scanner s = new Scanner(System.in);System.out.println("放入所存金额:");account.setDeposit(account.getDeposit() + money.MoneyExchange( money, s.nextInt()));// 这里也可以采用一个 try - catch 块处理 saveAccountInformation方法中遇到的异常,目前未采用saveAccountInformation(account);System.out.println("存储成功!!!");}@Overridepublic void withdraw(Money money, Account account) {Scanner s = new Scanner(System.in);System.out.println("输入要取出金额:");int draw = s.nextInt();if( draw > account.getDeposit() ) {System.out.println("余额不足!!!");}else {// 账户中的货币都是以人民币形式存储的,所以要把取出(存入)的货币转化成人民币account.setDeposit(account.getDeposit() - money.MoneyExchange( money, s.nextInt()));}}@Overridepublic void changeCipher(Account account) {Scanner s = new Scanner(System.in);System.out.println("请输入本用户身份证号:");String id = s.next();System.out.println("请输入本用户手机号:");String mobileNumber = s.next();String address = "E:\\Account";File file = new File(address);File[] list = file.listFiles();if( list != null ) {// 通过循环遍历目录中的文件,进行逐个查找for( File t : list) {Path find = Path.of(t.getAbsolutePath());String content = null;try {content = new String(Files.readAllBytes(find));} catch (IOException e) {throw new RuntimeException(e);}if( content.contains(id) && content.contains(mobileNumber) ) {// 将目标文件信息读取到一个Account对象中try (FileInputStream in = new FileInputStream(address + "\\" + t.getName())) {ObjectInputStream oos = new ObjectInputStream(in);try {Account result = (Account) oos.readObject();System.out.println("请输入新密码(由六位数组成):");result.setCipher(s.next());System.out.println("密码更改成功!!!");// 保存信息saveAccountInformation(result);} catch (ClassNotFoundException e) {throw new ClassCastException("更改密码时读取用户信息失败!!!");}in.close();oos.close();} catch (IOException e) {throw new RuntimeException(e);}break;}}}else {System.out.println("目录为空!!!");}}public boolean checkBalance(Account account) {Account result = retrieveAccountInformation( account.getAccountNumber(), account.getCipher());if ( result != null ) {System.out.println("账户余额为:" + result.getDeposit() + "RMB");return true;}else {System.out.println("账户余额查询失败,请重新输入账号和密码!!!");return false;// 如果查询失败可根据用户选择进行继续查询,这里通过返回值判断是否查询成功}}
}
Account类
该类是对账户的定义,包括了账户应当具有的属性
包括但不限于
- 账号
- 密码
- 手机号
- 余额
- 年利率(待商榷)
- 时间(待商榷)
- 用户id
package Account;import java.io.Serializable;// 因为要实现账户保存,所以要接Serializable接口
public class Account implements Serializable {private String accountNumber;private String cipher;private Double deposit;private Double annualInterestRate;private int time;private final String id;private final String mobileNumber;public Account(String accountNumber, String cipher, Double deposit, Double annualInterestRate, int time, String id, String mobileNumber) {this.accountNumber = accountNumber;this.cipher = cipher;this.deposit = deposit;this.annualInterestRate = annualInterestRate;this.time = time;this.id = id;this.mobileNumber = mobileNumber;}@Overridepublic String toString() {return "Account{" +"accountNumber='" + accountNumber + '\'' +", cipher='" + cipher + '\'' +", deposit=" + deposit +", annualInterestRate=" + annualInterestRate +", time=" + time +'}';}private int getTime() {return time;}public String getAccountNumber() {return accountNumber;}public String getCipher() {return cipher;}public Double getAnnualInterestRate() {return annualInterestRate;}public Double getDeposit() {return deposit;}public void setAccountNumber(String accountNumber) {this.accountNumber = accountNumber;}public void setDeposit(Double deposit) {this.deposit = deposit;}public void setAnnualInterestRate(Double annualInterestRate) {this.annualInterestRate = annualInterestRate;}public void setTime(int time) {this.time = time;}public void setCipher(String cipher) {this.cipher = cipher;}public String getId() {return id;}public String getMobileNumber() {return mobileNumber;}
}
User类
该类是面向用户的,主要实现了用户使用系统时的操作逻辑,通过用户输入的操作数来执行对应的操作。
package User;import Account.Account;
import Account.Operations.Operations;
import OperationInterface.LoginInterface;
import OperationInterface.MainInterface;
import OperationInterface.RegistrationInterface;import java.io.FileNotFoundException;
import java.util.Scanner;import static java.lang.System.exit;public class User {public void userOperation() throws FileNotFoundException {// 跳出首页画面提示用户/* ······· */Scanner s = new Scanner(System.in);Account account = null;Operations operation = new Operations();System.out.println("输入 1 登录账户 输入 2 创建新账户 ");int userOperation = s.nextInt();if(userOperation == 1){LoginInterface loginInterface = new LoginInterface();loginInterface.loginInterface();Operations operations = new Operations();//调用登录方法//operations.landAccount(); ////如何判断登录成功?成功则进入主界面MainInterface mainInterface = new MainInterface();mainInterface.mainInterface(); //展示主界面}else if (userOperation == 2){RegistrationInterface registrationInterface = new RegistrationInterface();registrationInterface.registrationInterface();Operations operations = new Operations();//调用创建账户方法//operations.createAccount(); }else {System.out.println("您进行的操作不合法!");}// 以下可以根据页面直接加操作/* ············· */}public void mainInterfaceOperation(){//主界面操作Scanner scanner = new Scanner(System.in) ;Operations operations = new Operations();int n = scanner.nextInt();if (n == 1){//调用存款方法//operations.saveMoney(); //}else if(n == 2){//调用取款方法//operations.withdraw(); //}else if(n == 3){//调用查询余额方法//operations.checkBalance() ;///}else if(n == 4){//调用货币交换方法 !!未实现}else if(n == 5){//调用修改密码方法//operations.changeCipher(); }else if(n == 6){//调用操作日志查询方法 !!未实现}else if(n == 7){//调用退出账户方法,返回登录界面//operations.logOut(); ///}else if(n == 8){//退出系统,即终止程序运行exit(0) ;}}
}
Area类 (父类)
在创建账户时,需要根据用户所在地区给出前几位数字,我们用一个Area父类来实现这一功能,每个不同的地区均是其子类
package Area;public class Area {public String name;public Area(String name) {this.name = name;}public String obtainNumber() {return null;}
}
货币大类
本周货币大类不在需要实现的范围内,故只进行了简单的架构
Money类(抽象类)
主要实现货币交换的方法,每个不同的币种均是其子类
package Currency;public abstract class Money {public Double exchangeRate; // 汇率, 人民币与该货币的比public abstract Double MoneyExchange( Money money, int num); // 某货币交换成人民币public abstract Double ExchangeMoney( Money money, int num);// 人民币交换成某货币
}
操作界面
目前实现了三个界面
- 登录界面
- 注册界面
- 主界面
界面的实现极其简单,无非是几个文件创建和输出的事情罢了。
LoginInterface类
package OperationInterface;import java.io.*;public class LoginInterface {public void loginInterface() throws FileNotFoundException {File file = new File("Login.txt"); //创建File类对象,并给出其相对路径,否则默认创建在当前路径下if (file.exists()) { //调用exists方法,判断文件是否存在fileInput(file); //如已存在,直接打开} else { //如不存在,执行创建操作try {file.createNewFile();fileInput(file);} catch (Exception e) {System.out.println("系统故障!");}}}private void fileInput(File file) {FileReader f = null;//文件读取对象BufferedReader f1 = null;//字符流对象try {f = new FileReader(file);f1 = new BufferedReader(f);//循环打印cc文件中的每行数据String str = null;while ((str = f1.readLine()) != null) {System.out.println(str);}} catch (Exception e) {System.out.println("系统故障!");} finally {try {f1.close();f.close();} catch (Exception e2) {System.out.println("系统故障!");}}}
}
MainInterface类
package OperationInterface;import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;public class MainInterface {public void mainInterface() throws FileNotFoundException {File file = new File("Main.txt"); //创建File类对象,并给出其相对路径,否则默认创建在当前路径下if (file.exists()) { //调用exists方法,判断文件是否存在fileInput(file); //如已存在,直接打开} else { //如不存在,执行创建操作try {file.createNewFile();fileInput(file);} catch (Exception e) {System.out.println("系统故障!");}}}private void fileInput(File file) {FileReader f = null;//文件读取对象BufferedReader f1 = null;//字符流对象try {f = new FileReader(file);f1 = new BufferedReader(f);//循环打印cc文件中的每行数据String str = null;while ((str = f1.readLine()) != null) {System.out.println(str);}} catch (Exception e) {System.out.println("系统故障!");} finally {try {f1.close();f.close();} catch (Exception e2) {System.out.println("系统故障!");}}}
}
RegistrationInterface类
package OperationInterface;import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;public class RegistrationInterface {public void registrationInterface() throws FileNotFoundException {File file = new File("Registration.txt"); //创建File类对象,并给出其相对路径,否则默认创建在当前路径下if (file.exists()) { //调用exists方法,判断文件是否存在fileInput(file); //如已存在,直接打开} else { //如不存在,执行创建操作try {file.createNewFile();fileInput(file);} catch (Exception e) {System.out.println("系统故障!");}}}private void fileInput(File file) {FileReader f = null;//文件读取对象BufferedReader f1 = null;//字符流对象try {f = new FileReader(file);f1 = new BufferedReader(f);//循环打印cc文件中的每行数据String str = null;while ((str = f1.readLine()) != null) {System.out.println(str);}} catch (Exception e) {System.out.println("系统故障!");} finally {try {f1.close();f.close();} catch (Exception e2) {System.out.println("系统故障!");}}}
}
三个界面的txt文档设计
//登录界面 登录账号:
密码://注册界面注册请输入身份证号:
请输入手机号:
请输入密码://主界面欢迎1.存款 2.取款
3.查询余额 4.货币交换
5.更改密码 6.操作日志查询
7.退出账户 8.退出系统
后言
本周主要实现了用户的部分基本操作,采用的主要手段为文件操作(文件的写入与读取也有博客记录Java文件操作(从创建文件到简单输入输出流)-CSDN博客),用于存储数据,设计操作界面等。在和朋友进行合作开发的过程中,我们也遇到了许多问题,比如当我们分析完项目需求后,双方就开始着手写代码实现,却没有提前沟通好代码逻辑,导致虽然写了注释,互相读代码时也遇到了不小的障碍(所以大家千万别学我们)
新手上路,水平有限,如有错误,还望海涵并指出!
与君共勉!