我试图以面向对象的方式体现一些基本的ATM操作,以供实践。会喜欢从结构,面向对象的原则的一些评论指针。另外,为了更好地掌握OO设计,我下一步应该做些什么(我想读更多的代码而不是书籍/视频,已经把我的思想从5年的教程中推出来了)。
假设--我的ATM实现包括创建一个用户并从一个ATM上打开一个银行帐户。
自动取款机业务-
帐户类别
package templates;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Account {
private long accountBalance;
private List miniStatement;
private boolean accountStatus;
private String accountPIN;
public Account() {
this.accountBalance = 10000;
this.accountStatus = true;
this.accountPIN = "1111";
this.miniStatement = new ArrayList<>();
}
public String doWithdraw(long amount) {
if(this.accountStatus) {
if(getBalance() > 0.00 && amount > 0.00 && getBalance() >= amount) {
this.accountBalance -= amount;
String str = "Account debited with $"+amount;
this.miniStatement.add(str);
return str;
}else
return "Amount entered is high, please enter less amount !!! ";
}else
return "Account is already closed";
}
public double getBalance() {
if(checkAccountStatus())
return this.accountBalance;
return -1.00;
}
public boolean changePIN(String newPin) {
if(checkAccountStatus()) {
this.accountPIN = newPin;
return true;
}
return false;
}
private boolean checkAccountStatus() {
return this.accountStatus;
}
public String closeAccount() {
if(checkAccountStatus()) {
String str = "Please collect $"+ getBalance();
this.accountStatus = false;
return str+". Account is now closed";
}
return "Account is already closed";
}
public Iterator printMiniStatement() {
return this.miniStatement.iterator();
}
}用户类
package templates;
public class User {
private String firstName;
private String lastName;
private String address;
private String phoneNumber;
public User(String firstName,String lastName,String address,String phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phoneNumber = phoneNumber;
}
public void setFirstName(String fname) {
this.firstName = fname;
}
public String getFirstName() {
return this.firstName;
}
public void setLastName(String lname) {
this.lastName = lname;
}
public String getLastName() {
return this.lastName;
}
public void setAddress(String addr) {
this.address = addr;
}
public String getAddress() {
return this.address;
}
public void setPhoneNumer(String phonenum) {
this.phoneNumber = phonenum;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
}主/测试类
package test;
import java.util.Iterator;
import templates.*;
public class ATMTest {
public static void main(String[] args) {
Account savings = new Account();
User user1 = new User("Dummy","Name","27, First Floor, Suok-I","8888888888");
System.out.printf("%s%n", "Account Balance is $"+savings.getBalance());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(50));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(5540));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(3350));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(1090));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(90));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(966));
System.out.println("-------------------------------------");
System.out.printf("%s%n", "Account Balance is $"+savings.getBalance());
System.out.println("-------------------------------------");
savings.changePIN("1611");
Iterator itr = savings.printMiniStatement();
System.out.printf("%20s%n", "MINI STATEMENT");
while(itr.hasNext()) {
System.out.printf("%s%n", itr.next());
}
System.out.println("-------------------------------------");
System.out.printf("%s%n", user1.getFirstName());
System.out.printf("%s%n", user1.getLastName());
System.out.printf("%s%n", user1.getAddress());
System.out.printf("%s%n", user1.getPhoneNumber());
System.out.println("-------------------------------------");
user1.setFirstName("Rain");
user1.setLastName("Man");
user1.setAddress("32, Second Floor, Suok-I");
user1.setPhoneNumer("9999999999");
System.out.printf("%s%n", user1.getFirstName());
System.out.printf("%s%n", user1.getLastName());
System.out.printf("%s%n", user1.getAddress());
System.out.printf("%s%n", user1.getPhoneNumber());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.closeAccount());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(1111));
System.out.println("-------------------------------------");
}
}发布于 2021-05-11 18:05:53
您的ATMTest中有一个类型问题。printMiniStatement-Method in Iterator itr = savings.printMiniStatement();有返回类型void,但是变量需要一个Iterator。因此,代码无法编译。
您应该介绍一些用户和帐户之间的关系,因为它们显然是相互关联的。例如:
List accounts添加到UserUser user添加到Account您应该添加一个ATM-Class,它负责执行撤回操作。这不应由帐户本身来完成。要了解更多信息,请看一下单一责任原则(下面的链接)。您还应该向帐户中添加一个字段String id。它可以与accountPin-field结合使用,以允许ATM实例进行某种身份验证。
正如吉尔伯特所指出的:在代表货币时不要使用浮点数。浮点表示不能100%准确,因此有时会丢失/添加几美分。使用整数/长代替。它们不会受到精确错误的影响,也不会导致这些很难确定的错误类型(下面的链接)。
以及为什么Account-Class只有一个指定任意值的无参数构造函数?
Further阅读:
您可以重写类‘toString-Method’,以便System.out.println(...)可以推断其实例的字符串表示形式。以下面的场景为例:创建一个新用户并立即打印出指定的值。在您的ATMTest-class中,您只是通过反复调用不同的getter来做到这一点。通过重写用户的"toString"-Method,可以将其缩写为:System.out.println(new User(...))
Further阅读:
只有在必须避免模糊/模糊的情况下才使用this。否则,它会使您的代码更难阅读。
Further阅读:
this:https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html使用白空间对您有利。在阅读某人的代码时,由空格创建的视觉空白是必要的指南。它们提供了额外的结构,从而提高了可读性。
Further阅读:
像import templates.*;这样的语句导入templates-package中的所有类。避免通配符-导入,因为它们可能导致麻烦的错误,当编译时,由于命名冲突。
Further阅读:
我只向您的代码标记点添加了几个注释,在这些地方可以实现上述点。Account类的运行方式与以前一样
package templates;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Account {
/*
"accountBalance" can be renamed to "balance" since "accountBalance" always belongs to an instance of "Account".
Preceding "Balance" by "account" doesn't add any information
*/
private double accountBalance;
private List miniStatement;
/*
"accountStatus" is an extremly broad term and may lead to confusion. If your goal was to mark an account as closed
consider renaming "accountStatus" to "isClosed"
*/
private boolean accountStatus;
private String accountPIN;
public Account() {
/*
the "this"-keyword is only required if you need to avoid ambiguity (this applies to most of your getters/setters as well!!)
take a look at your "User"-Constructor for more information (I left another comment over there :) )
*/
this.accountBalance = 10000.0;
this.accountStatus = true;
this.accountPIN = "1111";
this.miniStatement = new ArrayList<>();
}
public String doWithdraw(double amount) {
// Consistency! use either "this.accountStatus" or "checkAccountStatus()"
if(this.accountStatus) {
if(getBalance() > 0.00 && amount > 0.00 && getBalance() >= amount) {
this.accountBalance -= amount;
// use meaningful names e.g. "substatement"
String str = "Account debited with $"+amount;
this.miniStatement.add(str);
return str;
}else
return "Amount entered is high, please enter less amount !!! ";
}else
return "Account is already closed";
}
public double getBalance() {
if(checkAccountStatus())
return this.accountBalance;
// why should the balance of an disabled account be -1??
return -1.00;
}
// replace "changePIN" by "setPIN". The terms getter/setter are commonly in OOP. They make your code more readable to other programmers
public boolean changePIN(String newPin) {
if(checkAccountStatus()) {
this.accountPIN = newPin;
return true;
}
return false;
}
// replace "checkAccountStatus" by "getAccountStatus"
private boolean checkAccountStatus() {
return this.accountStatus;
}
public String closeAccount() {
if(checkAccountStatus()) {
System.out.printf("%s","Please collect $"+ getBalance());
this.accountStatus = false;
return ". Account is now closed";
}
return "Account is already closed";
}
public void printMiniStatement() {
if(checkAccountStatus()) {
Iterator itr = this.miniStatement.iterator();
System.out.printf("%20s%n", "MINI STATEMENT");
while(itr.hasNext()) {
System.out.printf("%s%n", itr.next());
}
}
}
}User类
package templates;
public class User {
private String firstName;
private String lastName;
private String address;
private String phoneNumber;
/*
Here, the "this"-keyword was necessary. Otherwise method parameters will shadow the field you want to assign a value to.
*/
public User(String firstName,String lastName,String address,String phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phoneNumber = phoneNumber;
}
/* why abbreviate "firstName" to "fname"? Simply use "firstName" as your method parameter.
This way you can avoid unnecessary confusion for other programmers. Keep the "this"-keyword to avoid ambiguity
*/
public boolean setFirstName(String fname) {
if(!fname.isEmpty()) {
this.firstName = fname;
return true;
}
return false;
}
public String getFirstName() {
return this.firstName;
}
public boolean setLastName(String lname) {
if(!lname.isEmpty()) {
this.lastName = lname;
return true;
}
return false;
}
public String getLastName() {
return this.lastName;
}
public boolean setAddress(String addr) {
if(!addr.isEmpty()) {
this.address = addr;
return true;
}
return false;
}
public String getAddress() {
return this.address;
}
public boolean setPhoneNumer(String phonenum) {
if(phonenum.length() == 10) {
this.phoneNumber = phonenum;
return true;
}
return false;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
}ATMTest类
package test;
import java.util.Iterator;
// avoid wildcard imports
import templates.*;
public class ATMTest {
public static void main(String[] args) {
Account savings = new Account();
User user1 = new User("Dummy","Name","27, First Floor, Suok-I","8888888888");
System.out.printf("%s%n", "Account Balance is $"+savings.getBalance());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(50));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(5540));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(3350));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(1090));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(90));
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(966));
System.out.println("-------------------------------------");
System.out.printf("%s%n", "Account Balance is $"+savings.getBalance());
System.out.println("-------------------------------------");
savings.changePIN("1611");
/*
// the following line can't be compiled -> incompatible types
Iterator itr = savings.printMiniStatement();
System.out.printf("%20s%n", "MINI STATEMENT");
while(itr.hasNext()) {
System.out.printf("%s%n", itr.next());
}
*/
System.out.println("-------------------------------------");
// use the "toString"-Method here to print "user1"
System.out.printf("%s%n", user1.getFirstName());
System.out.printf("%s%n", user1.getLastName());
System.out.printf("%s%n", user1.getAddress());
System.out.printf("%s%n", user1.getPhoneNumber());
System.out.println("-------------------------------------");
user1.setFirstName("Rain");
user1.setLastName("Man");
user1.setAddress("32, Second Floor, Suok-I");
user1.setPhoneNumer("9999999999");
System.out.printf("%s%n", user1.getFirstName());
System.out.printf("%s%n", user1.getLastName());
System.out.printf("%s%n", user1.getAddress());
System.out.printf("%s%n", user1.getPhoneNumber());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.closeAccount());
System.out.println("-------------------------------------");
System.out.printf("%s%n", savings.doWithdraw(1111));
System.out.println("-------------------------------------");
}
}
```#qcStackCode#https://codereview.stackexchange.com/questions/260493
复制相似问题