A feature-rich command-line banking application built with Java, demonstrating core software engineering principles and object-oriented design patterns.
-
Customer Management
- Register new customers
- View all registered customers
- Maintain customer profiles
-
Account Management
- Create checking and savings accounts
- View all customer accounts
- Close accounts (with zero balance requirement)
-
Account Types
- Checking Accounts: Standard accounts with unlimited withdrawals
- Savings Accounts: Special accounts with daily withdrawal limits (max 3 per day)
-
Transaction Processing
- Deposit funds
- Withdraw funds (with appropriate account constraints)
- Transfer funds between accounts
- View complete transaction history
-
Error Handling
- Insufficient funds validation
- Daily withdrawal limit enforcement
- Account and customer existence verification
- Graceful exception handling with custom exceptions
- Language: Java 21
- Build Tool: Maven
- Database: PostgreSQL
- Data Access: Raw JDBC (no ORM)
- Architecture Pattern: Repository Pattern with Service Layer
banking-cli/
├── src/main/
│ ├── java/
│ │ ├── Main.java # Application entry point
│ │ ├── exception/ # Custom exceptions
│ │ │ ├── AccountNotFoundException
│ │ │ ├── CustomerNotFoundException
│ │ │ ├── DailyWithdrawalLimitException
│ │ │ └── InsufficientFundsException
│ │ ├── model/ # Domain models
│ │ │ ├── Account.java
│ │ │ ├── CheckingAccount.java
│ │ │ ├── SavingsAccount.java
│ │ │ ├── Customer.java
│ │ │ ├── Transaction.java
│ │ │ └── enums/
│ │ │ ├── AccountType.java
│ │ │ └── TransactionType.java
│ │ ├── repository/ # Data access layer
│ │ │ ├── AccountRepository.java
│ │ │ ├── AccountRepositoryImpl.java
│ │ │ ├── CustomerRepository.java
│ │ │ ├── CustomerRepositoryImpl.java
│ │ │ ├── TransactionRepository.java
│ │ │ └── TransactionRepositoryImpl.java
│ │ ├── service/ # Business logic layer
│ │ │ ├── AccountService.java
│ │ │ ├── CustomerService.java
│ │ │ └── TransactionService.java
│ │ └── util/ # Utility classes
│ │ ├── DatabaseConnection.java
│ │ └── MenuHandler.java
│ └── resources/
│ ├── schema.sql # Database schema
│ └── db.properties # DB credentials (not committed)
└── pom.xml
The application implements the Repository pattern to abstract data access logic, making the code more maintainable and testable.
Business logic is separated into dedicated service classes (AccountService, CustomerService, TransactionService) that coordinate between the repository and presentation layers.
The Account class uses inheritance to create specialized account types (Checking, Savings) with different behavior while sharing common functionality.
- PostgreSQL installed and running
CREATE DATABASE banking_cli;psql -U postgres -d banking_cli -f src/main/resources/schema.sqlCreate src/main/resources/db.properties (this file is excluded from version control):
db.url=jdbc:postgresql://localhost:5432/banking_cli
db.user=your_username
db.password=your_passwordOnce the application starts, you'll be presented with a menu:
Welcome to Banking CLI
1. Register Customer
2. List All Customers
3. Open Account
4. View Customer Accounts
5. Deposit
6. Withdraw
7. Transfer
8. View Transaction History
9. Check Balance
10. Close Account
0. Exit
- Register a customer: Select option 1
- Open an account: Select option 3 (choose between Checking or Savings)
- Deposit funds: Select option 5
- Make a withdrawal: Select option 6 (Savings accounts limited to 3/day)
- View balance: Select option 9
- Check history: Select option 8
InsufficientFundsException: Thrown when withdrawal/transfer exceeds balanceDailyWithdrawalLimitException: Thrown when savings account withdrawal limit exceededAccountNotFoundException: Thrown when account doesn't existCustomerNotFoundException: Thrown when customer doesn't exist
Savings accounts implement a daily withdrawal limit of 3 transactions per calendar day, resetting at midnight. Attempting to exceed this limit throws a DailyWithdrawalLimitException.
All data is persisted in a PostgreSQL database using raw JDBC via PreparedStatement. Each repository implementation maps SQL result sets directly to Java objects with no ORM involved.