Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public class App {
public static void main(String[] args) throws Exception {
System.out.println("Hello, World!");
}
}
19 changes: 19 additions & 0 deletions src/BankAccount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
public class BankAccount {
private double balance;

public BankAccount(double initialBalance) {
this.balance = initialBalance;
}

public double getBalance() {
return balance;
}

public void deposit(double amount) {
balance += amount;
}

public void withdraw(double amount) {
balance -= amount;
}
}
39 changes: 39 additions & 0 deletions src/BaseTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import java.util.Calendar;

public class BaseTransaction implements TransactionInterface {
protected double amount;
protected Calendar date;
protected String transactionID;

// Constructor
public BaseTransaction(double amount, String transactionID) {
this.amount = amount;
this.date = Calendar.getInstance(); // Captures the current date/time
this.transactionID = transactionID;
}

@Override
public double getAmount() {
return amount; // [cite: 25]
}

@Override
public Calendar getDate() {
return date; // [cite: 26]
}

@Override
public String getTransactionID() {
return transactionID; // [cite: 27]
}

public void printTransactionDetails() { // [cite: 29]
System.out.println("Transaction ID: " + transactionID);
System.out.println("Date: " + date.getTime());
System.out.println("Amount: $" + amount);
}

public void apply(BankAccount ba) throws InsufficientFundsException { // [cite: 30]
System.out.println("Base transaction applied. No changes made to balance.");
}
}
12 changes: 12 additions & 0 deletions src/DepositTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public class DepositTransaction extends BaseTransaction {

public DepositTransaction(double amount, String transactionID) {
super(amount, transactionID);
}

@Override
public void apply(BankAccount ba) throws InsufficientFundsException { //
ba.deposit(amount);
System.out.println("Deposit of $" + amount + " applied. New balance: $" + ba.getBalance());
}
}
5 changes: 5 additions & 0 deletions src/InsufficientFundsException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
197 changes: 52 additions & 145 deletions src/Main.java
Original file line number Diff line number Diff line change
@@ -1,156 +1,63 @@
import Lecture1_adt.*; // Import all classes from Lecture1_adt package to be used in this client code

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.ArrayList;
import java.util.List;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
/*
* Client Code for accessing the Lecture1_adt.TransactionInterface.java module
*/
public class Main {

public static void testTransaction1() {
Calendar d1 = new GregorianCalendar(); // d1 is an Object [Objects are Reference types]
Lecture1_adt.Transaction1 t1 = new Lecture1_adt.Transaction1(1000, d1); // amount and d1 are arguments

System.out.println(t1.toString());
System.out.println("Lecture1_adt.TransactionInterface Amount: \t " + t1.amount);
System.out.println("Lecture1_adt.TransactionInterface Date: \t " + t1.date);

// Please note that the Client Codes can access the data in the class directly through the dot operator
// This kind of exposure is a threat to both the Representation Independence and Preservation of Invariants
}


/** @return a transaction of same amount as t, one month later
* This is a PRODUCER of the class Lecture1_adt.Transaction2
* This code will help demostrate the Design exposures still present in transaction2 class
* */

public static Transaction2 makeNextPayment(Transaction2 t) {
Calendar d = t.getDate();
d.add(Calendar.MONTH, 1);
return new Transaction2(t.getAmount(), d);
}

/*
Testing Transaction2 class
*/
public static void testTransaction2() {

Calendar d1 = new GregorianCalendar();

Lecture1_adt.Transaction2 t = new Lecture1_adt.Transaction2(1000, d1);

Lecture1_adt.Transaction2 modified_t = makeNextPayment(t);

System.out.println("\n\nState of the Object T1 After Client Code Tried to Change the Amount");
System.out.println("Lecture1_adt.TransactionInterface Amount: \t "+modified_t.getAmount());
System.out.println("Lecture1_adt.TransactionInterface Date: \t "+modified_t.getDate().getTime());

System.out.println("\n\nHow does T2 Look Like?????");
System.out.println("Lecture1_adt.TransactionInterface Amount: \t "+modified_t.getAmount());
System.out.println("Lecture1_adt.TransactionInterface Date: \t "+modified_t.getDate().getTime());

/* Please note that Although we have solved the problem of Transaction1
* And client code can no longer use the dot (.) operator to directly access the data
* There is still some exposure especially if we pass an object of a previous Transaction2 to create a new Transaction2 object
*/

}


/** @return a list of 12 monthly payments of identical amounts
* This code will help demostrate the Design exposures still present in transaction3 class
* */
public static List<Transaction3> makeYearOfPayments (int amount) throws NullPointerException {

List<Transaction3> listOfTransaction3s = new ArrayList<Transaction3>();
Calendar date = new GregorianCalendar(2024, Calendar.JANUARY, 3);


for (int i = 0; i < 12; i++) {
listOfTransaction3s.add(new Transaction3(amount, date));
date.add(Calendar.MONTH, 1);
public static void main(String[] args) {
System.out.println("========== STARTING TRANSACTION SYSTEM TESTS ==========");

// 1. Setup Bank Account
BankAccount account = new BankAccount(500.0);
System.out.println("Initial Balance: $" + account.getBalance());

// 2. Test DepositTransaction
System.out.println("\n--- 1. Testing Standard Deposit ---");
DepositTransaction deposit = new DepositTransaction(200.0, "TXN-DEP-001");
deposit.printTransactionDetails();
try {
deposit.apply(account);
} catch (InsufficientFundsException e) {
System.out.println("Error: " + e.getMessage());
}
return listOfTransaction3s;
}

/*
Testing Transaction3 class
*/
public static void testTransaction3() {

List<Transaction3> allPaymentsIn2024 = makeYearOfPayments(1000);

for (Transaction3 t3 : allPaymentsIn2024) {

// Display all the 12 Transactions
for (Transaction3 transact : allPaymentsIn2024) {
System.out.println("\n\n ::::::::::::::::::::::::::::::::::::::::::::\n");
System.out.println("Lecture1_adt.TransactionInterface Amount: \t "+transact.getAmount());
System.out.println("Lecture1_adt.TransactionInterface Date: \t "+transact.getDate().getTime());
}
// 3. Test Standard Withdrawal (Success)
System.out.println("\n--- 2. Testing Standard Withdrawal ---");
WithdrawalTransaction withdrawal1 = new WithdrawalTransaction(100.0, "TXN-WIT-001");
withdrawal1.printTransactionDetails();
try {
withdrawal1.apply(account);
} catch (InsufficientFundsException e) {
System.out.println("Error: " + e.getMessage());
}

/* Please Check all the 12 transactions displayed and hwo their dates look like
* Note that Although Transaction3 class resolves to an extent the exposure in Transaction2 class
* There is still some exposure especially if we pass an object of a previous Transaction3 to create a
* new Transaction3 object
*/
}


/** @return a list of 12 monthly payments of identical amounts
* This code Show that by judicious copying and defensive programming we eliminate the exposure in Transaction3
* As defined in the constructor of Transaction4 class
* */

public static List<Transaction4> makeYearOfPaymentsFinal (int amount) throws NullPointerException {

List<Transaction4> listOfTransaction4s = new ArrayList<Transaction4>();
Calendar date = new GregorianCalendar(2024, Calendar.JANUARY, 3);


for (int i = 0; i < 12; i++) {
listOfTransaction4s.add(new Transaction4(amount, date));
date.add(Calendar.MONTH, 1);
// 4. Test Reversal (From Phase 2)
System.out.println("\n--- 3. Testing Transaction Reversal ---");
withdrawal1.reverse();

// 5. Test Exception Handling (From Phase 3)
System.out.println("\n--- 4. Testing Insufficient Funds Exception ---");
WithdrawalTransaction withdrawal2 = new WithdrawalTransaction(1000.0, "TXN-WIT-002");
try {
withdrawal2.apply(account);
} catch (InsufficientFundsException e) {
System.out.println("EXPECTED EXCEPTION CAUGHT: " + e.getMessage());
}
return listOfTransaction4s;
}

/*
Testing Transaction3 class
*/
public static void testTransaction4() {

/*
* Call the function to make all the Twelve transaction in a year of our business
*/

List<Transaction4> transactionsIn2024 = makeYearOfPaymentsFinal(1200);

// Display all the 12 Transactions
for (Transaction4 transact : transactionsIn2024) {
System.out.println("\n\n ::::::::::::::::::::::::::::::::::::::::::::\n");
System.out.println("Lecture1_adt.TransactionInterface Amount: \t "+transact.getAmount());
System.out.println("Lecture1_adt.TransactionInterface Date: \t "+transact.getDate().getTime());
// 6. Test Partial Withdrawal (From Phase 3 Overloaded Method)
System.out.println("\n--- 5. Testing Partial Withdrawal ---");
WithdrawalTransaction withdrawal3 = new WithdrawalTransaction(800.0, "TXN-WIT-003");
withdrawal3.apply(account, true);

// 7. Test Polymorphism & Type Casting (Crucial Q4 Requirement)
System.out.println("\n--- 6. Testing Polymorphism & Type Casting ---");
// Creating a subtype object (DepositTransaction) but referencing it as the Base type
BaseTransaction polyTransaction = new DepositTransaction(50.0, "TXN-POLY-001");
polyTransaction.printTransactionDetails();

try {
// Because of late binding (polymorphism), this will run the DepositTransaction's apply()
// method, NOT the BaseTransaction's generic apply() method.
polyTransaction.apply(account);
} catch (InsufficientFundsException e) {
System.out.println("Error: " + e.getMessage());
}

// Please Take a look at all the 12 transaction now and compare with the outputs of the Transaction3 class
}


public static void main(String[] args) {
// This is the client code
// Uncomment the following lines to test the class which you would like to test

// testTransaction1()
// testTransaction2()
// testTransaction3()
// testTransaction4()
System.out.println("\n========== TESTS COMPLETED ==========");
}
}