Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

You want your bank application to be generic enough and be able to satisfy the needs of all the banks with as few changes as

You want your bank application to be generic enough and be able to satisfy the needs of all the banks with as few changes as possible. Consider the "Structural Patterns" for this assignment.

For each of the problems below, identify the patterns and show the class structure when the pattern is applied and provide justification.

Java implementation for the classes and provide the test results.

Part1 - YThe transactions for each account could be simple transactions, or transactions with logging capability, security capability, or a combination of any of these or more in the future.

Part2- The bank would like to provide statements to the customer. These could be monthly statements, quarterly statements, half-yearly, full year, or multi-year statements. Each higher level statement would recursively include its component statements.

Part3- The bank uses an external package for customer verification. These packages and its interfaces could change in the future.

import java.util.Date; import java.util.List; import java.util.ArrayList;

public abstract class Account {

private final String accountId; private final Date openDate; private Date closeDate;

private final Customer primaryOwner; private Customer jointOwner;

private AccountStatus accountStatus;

private Date jointOwnershipDate;

private int currentBalance;

private final List transactionList;

public Account(Customer primaryOwner, String accountId, Date openDate) { this.accountId = accountId; this.openDate = openDate; this.accountStatus = AccountStatus.Open; this.currentBalance = 0; this.transactionList = new ArrayList<>(); this.primaryOwner = primaryOwner; primaryOwner.addAccount(this); }

public Customer getPrimaryOwner() { return this.primaryOwner; }

public String getAccountId() { return this.accountId; }

public Date getOpenDate() { return this.openDate; }

public AccountStatus getAccountStatus() { return this.accountStatus; }

public int getCurrentBalance() { return this.currentBalance; }

public void setJointOwner(Customer jointOwner, Date jointOwnershipDate) { this.jointOwner = jointOwner; this.jointOwnershipDate = jointOwnershipDate; jointOwner.addAccount(this); }

public Customer getJointOwner() { return this.jointOwner; }

public Date getJointOwnershipDate() { return this.jointOwnershipDate; }

protected synchronized void addTransaction(Transaction t) {

if (this.accountStatus == AccountStatus.Close) throw new BankException("Account " + this.getAccountId() + "closed... Transaction not allowed");

if (t instanceof DepositTransaction) { deposit(t.getTransactionAmount()); transactionList.add(t); t.setEndingBalance(currentBalance);; /* Update Ending Balance after the Deposit transaction and add transaction details in the Transaction List*/ t.print(this); } else if (t instanceof WithdrawTransaction) { WithdrawTransaction wt = (WithdrawTransaction) t;

if (wt.getTransactionAmount() <= currentBalance){ withdraw(wt.getTransactionAmount()); } else { wt.setDescription("Not enough balance, withdrawl ignored"); } transactionList.add(wt); wt.setEndingBalance(currentBalance); /* Update Ending Balance after the withdraw transaction (Successfull or not successful) and add transaction details in the Transaction List*/ wt.print(this); } else if (t instanceof TransferTransaction) {

TransferTransaction tr = (TransferTransaction) t;

if (tr.getToAccount().accountStatus == AccountStatus.Close) throw new BankException("Account " + this.getAccountId() + " closed... Transaction not allowed");

tr.setDescription("Transfer from " + this.getAccountId() + " to " + tr.getToAccount().getAccountId()); this.transactionList.add(tr); tr.getToAccount().transactionList.add(tr); /* Update Ending Balance of source/destination accounts after the transfer transaction and add transaction details in the Transaction List*/ tr.print(this); }

}

private synchronized void deposit(int amount) { this.currentBalance += amount; }

private synchronized void withdraw(int amount) { this.currentBalance -= amount; }

public synchronized void closeAccount(Date closeDate) { this.accountStatus = AccountStatus.Close; this.closeDate = closeDate; }

public void printStatement(Date toDate) {

System.out.println(" \tTransactions for Account " + this.accountId + " Primary Owner: " + this.primaryOwner.getName() + " ");

for (int i=0; i< transactionList.size();i++) { Transaction t =(Transaction) transactionList.get(i); /* print each transaction from the account holder's Transaction List*/ t.print(this); } }

}

import java.util.HashMap; import java.util.Map; import java.util.Date;

public class Bank {

private final Map customerMap; private final Map accountMap;

private static Bank bankInstance;

private Bank() { customerMap = new HashMap<>(); accountMap = new HashMap<>(); }

public static synchronized Bank getBankInstance() { if (bankInstance == null) { bankInstance = new Bank(); } return bankInstance; }

public synchronized Customer createCustomer(String name, String customerId, Date registrationDate) throws BankException {

if(customerMap.containsKey(customerId)) { throw new BankException ("customerId already exists"); } else { Customer customer = new Customer(name, customerId, registrationDate); customerMap.put(customerId, customer); return customer; } }

public synchronized Customer lookupCustomer(String customerId) throws BankException { Customer customer = customerMap.get(customerId); if(customer == null) { throw new BankException ("customerId does not exist"); } else { return customer; } }

public synchronized Account createAccount(String customerId, AccountType accountType, String accountId, Date openDate, int initialAmount) throws BankException {

if(accountMap.containsKey(accountId)) { throw new BankException ("accountId already exists"); } else { Customer customer = customerMap.get(customerId); Account account = null; switch(accountType) { case Checking -> { account = new CheckingAccount(customer, accountId, openDate, initialAmount); } case Savings -> { account = new SavingsAccount(customer, accountId, openDate, initialAmount); } } accountMap.put(accountId, account); return account; } } public synchronized Account lookupAccount(String accountId) { Account account = accountMap.get(accountId); if (account == null) { new BankException("accountId does not exist"); } else { return account; } return account; }

public synchronized void setJointOwner(String accountId, String primaryOwnerId, String jointOwnerId, Date jointOwnershipDate) {

Account account = this.lookupAccount(accountId); Customer primaryOwner = this.lookupCustomer(primaryOwnerId); Customer jointOwner = this.lookupCustomer(jointOwnerId);

if ((account != null) && (primaryOwner != null) && (jointOwner != null)) { if ( (account.getPrimaryOwner() == primaryOwner) && (account.getJointOwner() == null) ) { account.setJointOwner(jointOwner, jointOwnershipDate); } }

}

public synchronized void createTransaction(TransactionType transactionType, Date date, int amount, String customerId, String sourceAccountId, String destinationAccountId) { switch (transactionType) {

case Deposit -> { makeDeposit(date, amount, customerId, sourceAccountId); break; } case Withdraw -> { makeWithdrawal(date, amount, customerId, sourceAccountId); break; } case Transfer -> { makeTransfer(date, amount, customerId, sourceAccountId, destinationAccountId); } } }

private synchronized void makeDeposit(Date date, int amount, String customerId, String accountId) { Customer customer = this.lookupCustomer(customerId); Account account = this.lookupAccount(accountId); new DepositTransaction(date, amount, customer, account); }

private synchronized void makeWithdrawal(Date date, int amount, String customerId, String accountId) { Customer customer = this.lookupCustomer(customerId); Account account = this.lookupAccount(accountId); if (account != null && ((account.getPrimaryOwner() == customer) || (account.getJointOwner() != null && account.getJointOwner() == customer)) ) { new WithdrawTransaction(date, amount, customer, account); } else new BankException("Customer is not owner or joint owner"); }

private synchronized void makeTransfer(Date date, int amount, String customerId, String fromAccountId, String toAccountId) { Customer customer = this.lookupCustomer(customerId); Account fromAccount = this.lookupAccount(fromAccountId); Account toAccount = this.lookupAccount(toAccountId); if (fromAccount != null && ((fromAccount.getPrimaryOwner() == customer) || (fromAccount.getJointOwner() != null && fromAccount.getJointOwner() == customer)) ){ new TransferTransaction(date, amount, customer, fromAccount, toAccount); } else new BankException("Customer is not owner or joint owner"); }

public synchronized void printStatement(String customerId, Date toDate) { Customer customer = this.lookupCustomer(customerId); if (customer != null) customer.printStatement(toDate); }

}

import java.text.DateFormat; import java.util.List; import java.util.ArrayList; import java.util.Date;

public class Customer { private final String name; private final String customerId; private final Date registrationDate; private final List accountList; public Customer(String name, String customerId, Date registrationDate) { this.name = name; this.customerId = customerId; this.registrationDate = registrationDate; this.accountList = new ArrayList<>(); }

public String getName() { return this.name; }

public String getCustomerId() { return this.customerId; }

public Date getRegistrationDate() { return this.registrationDate; }

public void addAccount(Account account) { accountList.add(account); /* Add the account to the customer's accountList */ }

public void printStatement(Date toDate) {

System.out.println(" BEGIN ACCOUNT STATEMENT - " + this.getName() + " - " + DateFormat.getDateInstance().format(toDate)); for(int i=0; i < accountList.size(); i++) { accountList.get(i).printStatement(toDate); }

System.out.println(" END ACCOUNT STATEMENT "); }

}

----------------------------------

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Managerial Accounting

Authors: Ramji Balakrishnan, Konduru Sivaramakrishnan, Geoff B. Sprinkle

2nd edition

1118385381, 978-1118385388

More Books

Students also viewed these Programming questions