首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOP ATM实现

OOP ATM实现
EN

Code Review用户
提问于 2021-05-08 12:36:29
回答 1查看 220关注 0票数 0

我试图以面向对象的方式体现一些基本的ATM操作,以供实践。会喜欢从结构,面向对象的原则的一些评论指针。另外,为了更好地掌握OO设计,我下一步应该做些什么(我想读更多的代码而不是书籍/视频,已经把我的思想从5年的教程中推出来了)。

假设--我的ATM实现包括创建一个用户并从一个ATM上打开一个银行帐户。

自动取款机业务-

帐户类别

  1. 开户
  2. 核对平衡
  3. 撤走
  4. 引脚更换
  5. 迷你声明
代码语言:javascript
复制
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();
            
    }
        
}

用户类

  1. 创建用户
  2. 设置名
  3. 取名
  4. 设置姓
  5. 取得姓
  6. 设置用户地址
  7. 获取用户地址
  8. 设定电话号码
  9. 弄到电话号码
代码语言:javascript
复制
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;
    }
}

主/测试类

代码语言:javascript
复制
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("-------------------------------------");
    }

}
EN

回答 1

Code Review用户

发布于 2021-05-11 18:05:53

只提交可编译代码以检查

您的ATMTest中有一个类型问题。printMiniStatement-Method in Iterator itr = savings.printMiniStatement();有返回类型void,但是变量需要一个Iterator。因此,代码无法编译。

逻辑与设计

您应该介绍一些用户和帐户之间的关系,因为它们显然是相互关联的。例如:

  • 用户可能有几个帐户:您可以将字段List accounts添加到User
  • 一个帐户只有一个用户:您可以将字段User user添加到Account

您应该添加一个ATM-Class,它负责执行撤回操作。这不应由帐户本身来完成。要了解更多信息,请看一下单一责任原则(下面的链接)。您还应该向帐户中添加一个字段String id。它可以与accountPin-field结合使用,以允许ATM实例进行某种身份验证。

正如吉尔伯特所指出的:在代表货币时不要使用浮点数。浮点表示不能100%准确,因此有时会丢失/添加几美分。使用整数/长代替。它们不会受到精确错误的影响,也不会导致这些很难确定的错误类型(下面的链接)。

以及为什么Account-Class只有一个指定任意值的无参数构造函数?

Further阅读:

toString-Method

您可以重写类‘toString-Method’,以便System.out.println(...)可以推断其实例的字符串表示形式。以下面的场景为例:创建一个新用户并立即打印出指定的值。在您的ATMTest-class中,您只是通过反复调用不同的getter来做到这一点。通过重写用户的"toString"-Method,可以将其缩写为:System.out.println(new User(...))

Further阅读:

this-keyword

只有在必须避免模糊/模糊的情况下才使用this。否则,它会使您的代码更难阅读。

Further阅读:

白色空间

使用白空间对您有利。在阅读某人的代码时,由空格创建的视觉空白是必要的指南。它们提供了额外的结构,从而提高了可读性。

Further阅读:

Wildcard-Import

import templates.*;这样的语句导入templates-package中的所有类。避免通配符-导入,因为它们可能导致麻烦的错误,当编译时,由于命名冲突。

Further阅读:

我只向您的代码标记点添加了几个注释,在这些地方可以实现上述点。Account类的运行方式与以前一样

代码语言:javascript
复制
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类

代码语言:javascript
复制
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类

代码语言:javascript
复制
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#
代码语言:javascript
复制
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/260493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档