I just "finished" a Udemy Java that involves building a banking application.
Here is the problem definition:
Scenario: You are a back-end developer and need to create an application to handle new customer bank requests.
Your application should do the following:
- Read a .csv file of names, social security numbers, account type and initial deposit
- Use a proper data structure to hold all these accounts
- Both savings and checkings accounts share the following properties:
- deposit()
- withdraw()
- transfer()
- showInfo()
11-Digit Account Number (generated with the following process: 1 or 2 depending on Savings or Checking, last two digits of SSN, unique 5-digit number, and random 3-digit number)
Savings Account holders are given a Safety Deposit Box, identified by a 3-digit number and accessed with a 4-digit code
- Checking Account holders are assigned a Debit Card with a 12-digit number and 4-digitPIN
Both accounts will use an interface that determines the base interest rate.
- Savings accounts will use 0.25 points less than the base rate
- Checking accounts will use 15% of the base rate
The show info method should reveal relevant account information as well as information specific to the Checking account or Savings account
I'm trying to follow the SOLID Principles of Programming while creating new applications. I was hoping to get some feedback on my code, in categories such as things I did well, things I could improve on (such as a better way to implement something). For example, some feedback could be: "Don't do this method in this class, it should be done in a separate class because of this reason."
I will attach my Account
and AccountTranscations
class in this post. But if you would like to see the other classes used in this project, go to my repository.
Account Class:
package bank;
import utilities.Generate;
import utilities.Watch;
public abstract class Account implements Rate
{
protected String name;
protected int ssn;
protected String dateOfCreation;
protected long accountNum;
protected double balance;
protected double rate;
protected int accountPin;
public Account(String name, int ssn, double initialDeposit, int accountPin)
{
Watch watch = new Watch();
this.name = name;
this.ssn = ssn;
this.balance = initialDeposit;
this.accountPin = accountPin;
dateOfCreation = watch.getDateTime();
//System.out.println(dateOfCreation);
rate = getRate();
}
//get the rate
//implementation will be dependent on the type of account
public abstract double getRate();
//Getters
public double getBalance()
{
return balance;
}
public long getAccountNum()
{
return accountNum;
}
public int getPin()
{
return accountPin;
}
public String getName()
{
return name;
}
//Setters
//attempt to set a 4-digit pin to the specified account
public void setPin(int accountPin)
{
if (!isValidPinWidth(accountPin)) return;
this.accountPin = accountPin;
System.out.println("New Pin Set");
}
public void setBalance(double balance)
{
this.balance = balance;
}
//check if the pin entered is 4 digits
public boolean isValidPinWidth(int accountPin)
{
if ((accountPin > 9999) || (accountPin < 0))
{
System.out.println("Failure: Invalid pin.");
return false;
}
else return true;
}
//check if the amount requested to withdrawn can be withdrawn from the specified account
public boolean isValidWithdrawal(double amount)
{
if (balance - amount < 0)
{
System.out.println("Failure: Account " + accountNum + " does not have sufficient funds.");
return false;
}
else return true;
}
//check if the pin attempted is valid
public boolean checkPinAttempt(int pinAttempt)
{
if (pinAttempt == accountPin)
{
//System.out.println("\nValid Pin Entry");
return true;
}
else
{
System.out.println("Invalid Pin Entry");
return false;
}
}
//generate the 11-digit account number
//1 or 2 depending on Savings or Checking, last two digits of SSN, unique 5-digit number
//and random 3-digit number
protected long generateAccountNum(int accountType)
{
Generate generate = new Generate();
long tempAccountNum = (long)(accountType * Math.pow(10, 10));
tempAccountNum += (ssn % 100) * Math.pow(10, 8);
tempAccountNum += generate.random(5) * Math.pow(10, 3);
tempAccountNum += generate.random(3);
return tempAccountNum;
}
//generate a 4 digit pin
public void generatePin()
{
accountPin = (int)(new Generate().random(4));
System.out.println("New Generated Pin: " + accountPin);
}
//attempt to unlock the specified account with the specified 4-digit pin
public boolean unlock(int pinAttempt)
{
if (!checkPinAttempt(pinAttempt))
{
//System.out.println("Account: Locked");
//System.out.println("Failure: Incorrect Pin");
return false;
}
else
{
System.out.println("Account " + getAccountNum() + ": Unlocked");
return true;
}
}
//lock the account
public void lock()
{
System.out.println("Account " + accountNum + ": Locked");
}
//show everything about the account
protected void showInfo()
{
StringBuilder sb = new StringBuilder();
sb.append("\nName: " + name);
sb.append("\nSSN: " + ssn);
sb.append("\nBalance: $" + balance);
sb.append("\nRate: " + rate + "%");
sb.append("\nAccount Number: " + accountNum);
sb.append("\nAccount Pin Number: " + accountPin);
sb.append("\nDate of Account Creation: " + dateOfCreation);
System.out.println(sb.toString());
}
}
AccountTransactions Class:
package bank;
import bank.Account;
public class AccountTransactions
{
public AccountTransactions()
{
}
//print the type of transaction being made
private void printTranscation(Account account, double amount, String transaction)
{
System.out.println("Account Number: " + account.getAccountNum());
System.out.println(transaction + ": $" + amount);
//System.out.println("New Balance: $" + account.getBalance());
}
//print the type of request being made
private void printRequest(String request)
{
System.out.println("\n" + request + " Request Recieved");
}
//deposit the specified amount of money into the specified account
public void deposit(Account targetAccount, double amount)
{
printRequest("Deposit");
targetAccount.setBalance(targetAccount.getBalance() + amount);
printTranscation(targetAccount, amount, "Deposited");
}
//attempt to withdraw the specified amount of money from the source account
public void withdraw(Account sourceAccount, double amount)
{
printRequest("Withdraw");
if (!sourceAccount.isValidWithdrawal(amount)) return;
sourceAccount.setBalance(sourceAccount.getBalance() - amount);
printTranscation(sourceAccount, amount, "Withdrawn");
}
//attempt to transfer the specified amount of money from the source account
//to the target account
public void transfer(Account sourceAccount, Account targetAccount, double amount)
{
printRequest("Transfer");
if (!sourceAccount.isValidWithdrawal(amount)) return;
withdraw(sourceAccount, amount);
deposit(targetAccount, amount);
}
//calculate the accrued interest and add it to the account's balance
public void accrueInterest(Account targetAccount)
{
printRequest("Accrue Interest");
double accruedInterest = (targetAccount.getBalance() * (targetAccount.getRate()/100.0));
targetAccount.setBalance(targetAccount.getBalance() + accruedInterest);
printTranscation(targetAccount, accruedInterest, "Accrued Interest");
}
}