# Joker **Repository Path**: song-sinker/joker ## Basic Information - **Project Name**: Joker - **Description**: No description available - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-26 - **Last Updated**: 2025-05-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Joker --- ## Student Info + Chinese Name: 宋豪杰 + English Name: Joker + Student Number: 2023905496 --- ## Project Goal This project aims to create a C++ console application simulating a banking system with multiple account types, supporting various transactions and reporting functions. Through this project, developers can consolidate and deepen their understanding and application of C++ language features such as interfaces, inheritance, function and operator overloading, classes and structs, multi-file project organization, header file management, and namespaces. --- ## System Features and Options This banking system offers the following main operational functions: * **Customer Account Creation**: When registering a new customer, the system automatically creates separate `Savings Accounts` and `Checking Accounts` for them. * **Access Customer Account**: Users can access existing customers by their name to view account information and perform operations. * **Display All Bank Accounts**: The system can display a list of all customers' `Savings Accounts` and `Checking Accounts` along with their basic information. * **Inter-Account Transfers**: * `Savings Accounts` can only transfer funds to a `Checking Account` under the same customer's name. * `Checking Accounts` can transfer funds to any other account within the system. * **Deposits and Withdrawals**: * Deposits are only supported for `Checking Accounts`. * Withdrawals are only supported from `Checking Accounts`. * **Transaction Logging**: All deposits, withdrawals, and transfer operations are recorded by the system as unique transactions. * **Generate Transaction Reports**: The system supports generating three types of transaction report files: * **Global Transaction Report**: Contains all transaction records for all accounts in the system, sorted chronologically. * **Customer Transaction Report**: Contains all transaction records for all accounts altında a specific customer, sorted chronologically. * **Account Transaction Report**: Contains all transaction records for a specific bank account, sorted chronologically. * **Unique Account ID**: Each bank account has a unique, randomly generated China UnionPay card-style account ID. * **Menu-Driven Interaction**: The system interacts with the user via console menus. --- ## Architecture Overview This section describes the overall software architecture of the `NovaBank` system, its core classes and their relationships, and explains some key design decisions. ### Overall Architecture The `NovaBank` system is designed and implemented using the Object-Oriented Programming (OOP) paradigm. The system's core functionality revolves around a series of well-defined classes that simulate key entities in a banking system (e.g., customers, accounts) and core operations (e.g., transactions, report generation). The project adheres to the following main principles: * **Modular Design**: By dividing different functional logics into independent classes (e.g., `BankSystem` for core business logic, `UIManager` for user interaction, `ReportGenerator` for report generation), code maintainability and extensibility are enhanced. * **Multi-File Organization**: Each class has its own header file (`.h`) and implementation file (`.cpp`), uniformly placed in the `include/nova_bank` and `src` directories for ease of management and compilation. * **Namespaces**: All custom classes and types are encapsulated within the `nova_bank` namespace to avoid potential naming conflicts. * **Separation of Concerns**: User interface logic is separated from core business logic, allowing them to be modified and evolved independently. ### Key Design Decisions During the development of the `NovaBank` system, several key design decisions were made to meet project requirements and ensure code quality: * **Screen Clearing Strategy and User Experience**: * The system's screen clearing operation is carefully designed and does not occur after every user input. Clearing mainly happens after a user completes an operational unit and confirms via the `"Press Enter to continue..."` prompt, before returning to a previous menu or the main menu. * **Rationale**: 1. **Information Retention**: During multi-step operations (e.g., viewing customer account info then accessing a specific account), key information (like the customer's `Savings Account ID` and `Checking Account ID`) remains on screen. This prevents users from frequently returning to the main menu or memorizing these IDs for subsequent operations (e.g., entering a recipient account ID during a transfer), improving usability. 2. **Preventing Information Overload and Interface Clutter**: After an operational unit (e.g., registering a customer, making a deposit) is completed, relevant prompt information has been displayed. Guiding the user to confirm with `"Press Enter to continue..."` and then clearing the screen keeps the interface tidy and provides a clean view for the next operation. 3. **Sense of Logical Flow Segmentation**: Combining screen clearing with `"Press Enter to continue..."` gives users a sense of completing a small task or flow segment, making the interaction process more natural and organized, rather than an unannounced loss of screen information. * An initial screen clear also occurs at program startup to provide a clean starting interface. * **Account System and Inheritance**: * The `Account` class is designed as an **abstract base class** (interface), defining common attributes (e.g., account ID, balance, owner) and behaviors (e.g., get balance, add transaction record, transfer) for all account types. Some behaviors like `canDeposit`, `canWithdraw`, `deposit`, `withdraw`, `transfer`, and account type-related `getAccountTypeString`, `getAccountType` are declared as **pure virtual functions**, forcing derived classes to implement them according to their specific characteristics. * `SavingsAccount` and `CheckingAccount` publicly inherit from `Account` and implement their specific logic. For example, deposit and withdrawal functions for `Savings Accounts` are disabled (`canDeposit`/`canWithdraw` always return `false`, `deposit`/`withdraw` perform no actual operation), and their transfer functionality is limited to transferring only to the same customer's `Checking Account`. `Checking Accounts`, however, allow deposits, withdrawals, and transfers to any account. * **Account ID and Transaction ID Generation**: * The `IdGenerator` class is responsible for generating unique bank account IDs in a specific format (`"62XX-YYYY-ZZZZ-AAAA"`) and unique transaction IDs (`"TXXXXXXX"`). * By internally maintaining a set of generated IDs (`std::unordered_set`), `IdGenerator` ensures ID uniqueness, performing collision detection and regeneration until a unique ID is obtained. * **Transaction Encapsulation and History Logging**: * The `Transaction` class encapsulates all relevant information for a single transaction, including transaction ID, type (deposit, withdrawal, transfer in, transfer out), amount, timestamp, notes, source account ID, and destination account ID. * Each `Account` object maintains a `std::vector` as its transaction history. * `BankSystem` also maintains a global list of transactions for generating global transaction reports. When an account transaction occurs, it is added to both the account's own history and the bank system's global record. * **Separation of User Interface and Business Logic**: * The `UIManager` class acts as the main manager for the user interface, responsible for displaying menus, receiving user input, and delegating user action requests to appropriate handling modules. * Core banking business logic is primarily handled by the `BankSystem` class and auxiliary `AccountActionHandler` and `CustomerActionHandler` classes. This separation allows UI modifications and business logic adjustments to be made relatively independently, reducing coupling. * `AccountActionHandler` and `CustomerActionHandler` further encapsulate operations under specific sub-menus (e.g., account deposits/withdrawals, customer transaction inquiries), making the `UIManager`'s main loop logic clearer. * **Report Generation Mechanism**: * The `ReportGenerator` class is specifically responsible for generating various transaction report files (global, customer, account reports). * It retrieves necessary data from `BankSystem` (for global transactions or customer lists) or directly from `Customer`/`Account` objects (for specific entity transaction histories), then formats and outputs the data to text files. Filenames include entity identifiers and generation dates to ensure report uniqueness and recognizability. * **Class Canonical Form**: * Major classes in the project adhere to C++ **canonical form** requirements, providing necessary special member functions. * **Manual Memory Management**: The project also shows how raw pointer lifecycles are managed by hand. For example, `CustomerRepository` stores and manages all `Customer` objects. It uses a `std::vector` for raw pointers to `Customer` objects created with `new`. The `CustomerRepository` destructor loops through and `delete`s these `Customer` objects to free memory. To avoid problems like double deletion or dangling pointers from managing raw pointers, `CustomerRepository`'s copy constructor and copy assignment operator are deleted (`=delete`). This shows direct memory control where needed. * **Smart Pointers and Copying**: For other classes like `Customer`, which use `std::unique_ptr` for members (like account objects), copying is handled carefully. The copy constructor and assignment create a **"nominal copy"** (copying basic info; `std::unique_ptr` members are handled as per their rules, often meaning the copy gets null or specially managed pointers). This prevents double deletion and makes resource management easier. For classes like `BankSystem` that handle complex resources or shouldn't be copied, copy operations are simply deleted (`=delete`). * These design decisions ensure that different classes adopt appropriate memory management strategies and copy control mechanisms based on their responsibilities and the types of resources they manage, demonstrating both the ability to control memory manually and the use of modern C++ smart pointers for convenience and safety. The provided special member functions include: * Default Constructor * Parameterized Constructor * Copy Constructor * Copy Assignment Operator * Destructor (if resource management is needed) * Depending on the specific characteristics of a class and its member variable types (e.g., reference members, `std::unique_ptr`, resources requiring **deep copy**), these special member functions are appropriately declared as `=default` (using the compiler-generated default version), `=delete` (prohibiting copy/assignment), or explicitly defined to implement specific copy/assignment semantics or resource management logic. --- ## Class Documentation This section details the main classes in the `NovaBank` system, including their responsibilities, key attributes, and core methods. ### `BankSystem` - **Purpose/Responsibility**: Acts as the core engine of the banking system, responsible for managing customer information, bank accounts, global transaction records, and coordinating major operations within the system. - **Key Attributes**: - `m_customerRepository`: `CustomerRepository` - Customer data repository for storing and retrieving customer objects. - `m_globalTransactions`: `std::vector` - Global list storing all transactions that occurred in the system. - `m_idGenerator`: `IdGenerator` - Used to generate unique customer IDs, account IDs, and transaction IDs. - **Key Methods**: - `registerCustomer(name)`: Registers a new customer and automatically creates `Savings Accounts` and `Checking Accounts` for them. - `findCustomerByName(name)`: Finds and returns a `customer object` by customer name. - `findAccountById(accountId)`: Finds and returns an `account object` by account ID. - `recordTransaction(transaction)`: Records a transaction in the global transaction list and the transaction history of the relevant accounts. - `getAllGlobalTransactions()`: Returns a constant reference to all global transactions. - `getCustomers()`: Returns a constant reference to all customer objects. ### `CustomerRepository` - **Purpose/Responsibility**: Responsible for storing and managing all `Customer` objects in the system. - **Key Attributes**: - `m_customers`: `std::vector` - Vector storing pointers to `Customer` objects. - **Key Methods**: - `addCustomer(customer)`: Adds a new customer to the repository. - `findCustomerByName(name)`: Finds and returns a `customer object pointer` by customer name. - `getAllCustomers()`: Returns a constant reference to all `customer object pointers`. - `~CustomerRepository()`: Destructor, responsible for releasing the memory of `customer objects` stored in the repository. ### `Customer` - **Purpose/Responsibility**: Represents a bank customer, containing personal information and their `Savings Account` and `Checking Account`. - **Key Attributes**: - `m_customerId`: `std::string` - Unique customer identifier ID. - `m_name`: `std::string` - Customer's name. - `m_savingsAccount`: `std::unique_ptr` - Unique pointer to the customer's `Savings Account`. - `m_checkingAccount`: `std::unique_ptr` - Unique pointer to the customer's `Checking Account`. - `m_bankSystem`: `BankSystem*` - Pointer to the owning bank system object. - **Key Methods**: - `getName()`: Returns the customer's name. - `getSavingsAccount()`: Returns a pointer to the customer's `Savings Account`. - `getCheckingAccount()`: Returns a pointer to the customer's `Checking Account`. - `getAllTransactionsChronologically()`: Collects and returns all transaction records for this customer's accounts, sorted chronologically. ### `Account` (Abstract Base Class) - **Purpose/Responsibility**: Serves as an **abstract base class** for all account types, defining common attributes and behavioral interfaces for bank accounts. - **Key Attributes**: - `m_accountId`: `std::string` - Unique account ID. - `m_balance`: `double` - Current account balance. - `m_owner`: `Customer*` - Pointer to the account owner (customer). - `m_bankSystem`: `BankSystem*` - Pointer to the owning bank system object. - `m_transactionHistory`: `std::vector` - Records all transactions for this account. - **Key Methods (some are pure virtual)**: - `getAccountId()`: Returns the account ID. - `getBalance()`: Returns the current account balance. - `getOwner()`: Returns the account owner. - `addTransactionToHistory(transaction)`: Adds a transaction to the account's transaction history. - `getTransactionHistory()`: Returns a constant reference to the account's transaction history. - `receiveCredit(amount, type, sourceAccId, note)`: Account receives a credit. - `getAccountTypeString() const = 0`: (Pure virtual) Returns the string representation of the account type. - `getAccountType() const = 0`: (Pure virtual) Returns the account type enum value. - `canDeposit(amount) const = 0`: (Pure virtual) Checks if the specified amount can be deposited into this account. - `canWithdraw(amount) const = 0`: (Pure virtual) Checks if the specified amount can be withdrawn from this account. - `deposit(amount, note) = 0`: (Pure virtual) Deposits funds into the account. - `withdraw(amount, note) = 0`: (Pure virtual) Withdraws funds from the account. - `transfer(destAccId, amount, note) = 0`: (Pure virtual) Transfers funds from this account to another. ### `SavingsAccount` - **Purpose/Responsibility**: Represents a `Savings Account`, inherits from `Account`. `Savings Accounts` typically have deposit and withdrawal restrictions, and their transfer functionality may also be limited (e.g., only to the same customer's `Checking Account`). - **Key Methods**: - Implements **pure virtual functions** defined in the `Account` base class, defining specific deposit, withdrawal, and transfer logic according to the characteristics of a `Savings Account`. - `deposit(amount, note)`: Usually does not allow direct deposits or the operation is ineffective. - `withdraw(amount, note)`: Usually does not allow direct withdrawals or the operation is ineffective. - `transfer(destAccId, amount, note)`: Implements specific transfer logic, such as only allowing transfers to the same customer's `Checking Account`. ### `CheckingAccount` - **Purpose/Responsibility**: Represents a `Checking Account`, inherits from `Account`. `Checking Accounts` typically support free deposits, withdrawals, and transfers to any other account. - **Key Methods**: - Implements **pure virtual functions** defined in the `Account` base class, defining specific deposit, withdrawal, and transfer logic according to the characteristics of a `Checking Account`. - `deposit(amount, note)`: Deposits funds into the `Checking Account`. - `withdraw(amount, note)`: Withdraws funds from the `Checking Account`. - `transfer(destAccId, amount, note)`: Transfers funds from the `Checking Account` to a specified account within the system. ### `Transaction` - **Purpose/Responsibility**: Encapsulates all relevant information for a single bank transaction (e.g., deposit, withdrawal, transfer). - **Key Attributes**: - `m_transactionId`: `std::string` - Unique transaction ID. - `m_type`: `TransactionType` - Transaction type (e.g., `DEPOSIT`, `WITHDRAWAL`, `TRANSFER_OUT`, `TRANSFER_IN`). - `m_amount`: `double` - Transaction amount. - `m_timestamp`: `std::chrono::system_clock::time_point` - Timestamp of when the transaction occurred. - `m_note`: `std::string` - Transaction notes. - `m_sourceAccountId`: `std::string` - Source account ID for the transaction (if applicable). - `m_destinationAccountId`: `std::string` - Destination account ID for the transaction (if applicable). - **Key Methods**: - Provides public methods to get various transaction attributes (ID, type, amount, timestamp, notes, etc.). - `transactionTypeToString(type)`: (Static method) Converts the `transaction type enum` to a user-readable string. ### `IdGenerator` - **Purpose/Responsibility**: Responsible for generating unique account IDs and transaction IDs in the system, ensuring they conform to a specific format and are not repeated. - **Key Attributes**: - `m_generatedAccountIds`: `std::unordered_set` - Stores generated account IDs for uniqueness checking. - `m_generatedTransactionIds`: `std::unordered_set` - Stores generated transaction IDs for uniqueness checking. - **Key Methods**: - `generateFullAccountId(type)`: Generates a unique account ID in the `"China UnionPay card"` style based on the account type. - `generateTransactionId()`: Generates a unique transaction ID. - `isAccountIdUnique(id)`: Checks if the given account ID has already been used. ### `UIManager` - **Purpose/Responsibility**: User Interface Manager, responsible for handling main user interaction flows, such as displaying the main menu, receiving user selections, and dispatching operations to appropriate handling modules. - **Key Attributes**: - `m_bankSystem`: `BankSystem&` - Reference to the core banking system. - `m_reportGenerator`: `ReportGenerator` - Report generator object. - `m_accountActionHandler`: `AccountActionHandler` - Handler for account-related operations. - `m_customerActionHandler`: `CustomerActionHandler` - Handler for customer-related operations. - **Key Methods**: - `displayMainMenuAndLoop()`: Displays the main menu and enters the user interaction loop, processing user selections until the user chooses to exit. ### `AccountActionHandler` - **Purpose/Responsibility**: Responsible for handling secondary menu operations related to specific bank accounts, such as deposits, withdrawals, transfers, and querying account transactions. - **Key Attributes**: - `m_bankSystem`: `BankSystem&` - Reference to the core banking system. - `m_reportGenerator`: `ReportGenerator&` - Reference to the report generator. - **Key Methods**: - `displayAccountOptionsMenu(account)`: Displays an account operations sub-menu for the given account and handles user input. ### `CustomerActionHandler` - **Purpose/Responsibility**: Responsible for handling secondary menu operations related to specific customers, such as viewing customer information, accessing customer accounts, and generating customer transaction reports. - **Key Attributes**: - `m_reportGenerator`: `ReportGenerator&` - Reference to the report generator. - `m_accountActionHandler`: `AccountActionHandler&` - Reference to the account action handler, used for further accessing account operations under the customer menu. - **Key Methods**: - `displayCustomerSubMenu(customer)`: Displays a customer operations sub-menu for the given customer and handles user input. ### `ReportGenerator` - **Purpose/Responsibility**: Specifically responsible for generating various types of transaction report files, such as global transaction reports, transaction reports for specific customers, and transaction reports for specific accounts. - **Key Attributes**: - `m_bankSystem`: `const BankSystem&` - Constant reference to the core banking system, used to obtain data needed for report generation. - **Key Methods**: - `generateGlobalTransactionReportFile()`: Generates a global report file containing all transactions. - `generateCustomerReportFile(customer)`: Generates a transaction report file for all accounts of a specified customer. - `generateAccountReportFile(account)`: Generates a transaction report file for a specified account. ### `DateTimeUtils` - **Purpose/Responsibility**: Provides date and time related utility functions, mainly formatting timestamps. - **Key Methods**: - `formatTimestamp(tp, format)`: (Static method) Formats a `std::chrono::system_clock::time_point` timestamp into a string of the specified format. ### `Types` - **Purpose/Responsibility**: Defines widely used enumeration types in the project, such as account type (`AccountType`) and transaction type (`TransactionType`). - **Key Enumerations**: - `AccountType`: e.g., `SAVINGS`, `CHECKING`. - `TransactionType`: e.g., `DEPOSIT`, `WITHDRAWAL`, `TRANSFER_IN`, `TRANSFER_OUT`. --- ## Compilation and Running Guide ### Environment Requirements - C++ compiler supporting `C++17` or higher (e.g., `GNU g++` or `Clang`). - `make` build tool. ### Compilation Steps 1. **Navigate to Project Directory**: Open a terminal or command line interface and use the `cd` command to switch to the root directory of this project: ```bash cd NovaBank ``` 2. **Clean Old Build Files (Optional but Recommended)**: To ensure a clean build, first run: ```bash make clean ``` (This step will delete any previous build files in the `build/` directory.) 3. **Execute Compilation Command**: Then, compile the project using the following command: ```bash make ``` This command will execute the compilation and linking process according to the `Makefile` configuration. ### Running Steps 1. **Locate Executable File**: If the compilation is successful without errors, the `make` command will generate an executable file named `NovaBank` (or `NovaBank.exe`, depending on the OS) in the `build/` folder under the project root. 2. **Launch Program**: Finally, you can run the program with the following command: ```bash ./build/NovaBank ``` After the program starts, you will see the main menu and can operate according to the on-screen prompts. --- ## Technical Requirements Implementation This project strives to follow good programming practices and modern C++ features to meet technical requirements. ### Clean Code Principles - **Naming Conventions**: Variables, functions, classes, etc., use clear and consistent naming conventions (e.g., `camelCase` or `snake_case`) to make their purpose easy to understand. - **Single Responsibility Principle (SRP)**: Each class and function should ideally be responsible for only one clear function, avoiding overly bloated and complex modules. - **Code Formatting**: Maintain consistent code indentation, spacing, and line break style to improve code readability. - **Comments**: Add necessary comments for complex logic, important design decisions, or non-obvious code segments, but do not overuse comments. - **Avoid Repetition (DRY - Don't Repeat Yourself)**: Reduce duplicate code through function encapsulation, class inheritance, etc. ### Object-Oriented Design (OOP) - **Interfaces (Abstract Classes)**: The `Account` class is designed as an **abstract base class**, defining a common interface that all account types must implement through **pure virtual functions**, such as deposit, withdrawal, and transfer operations. This allows the system to handle different types of accounts polymorphically. - **Inheritance**: `SavingsAccount` and `CheckingAccount` classes publicly inherit from the `Account` **abstract base class**. They not only inherit common account attributes and behaviors but also implement specific functionalities based on their respective business rules (e.g., transfer restrictions for `Savings Accounts`, free deposit/withdrawal for `Checking Accounts`). - **Encapsulation**: Class data members (attributes) are usually declared as `private` or `protected`. External code can only access and modify this data through the public member functions (methods) provided by the class. This hides internal implementation details, protects data integrity, and reduces coupling between modules. - **Polymorphism**: Using base class pointers or references to point to derived class objects and calling overridden virtual functions at runtime achieves dynamic binding and polymorphic behavior, for example, when processing transfers for different types of accounts. ### Modern C++ Features - **Namespaces (`namespace`)**: All custom classes, functions, and types in the project are encapsulated within the `nova_bank` **namespace**, effectively avoiding naming conflicts with the global scope or other libraries. - **Multi-File Project Organization**: The project code is reasonably divided into multiple files. Each class typically has its own header file (`.h` or `.hpp`) for declarations and an implementation file (`.cpp`) for definitions. This structure facilitates modular management, separate compilation, and team collaboration. - **Header Guards**: All header files use `#pragma once` directives or traditional macro guards (`#ifndef H_FILENAME_H ... #endif`) to prevent them from being included multiple times in a compilation unit, avoiding compilation errors and unnecessary compilation time. - **Standard Library Containers and Algorithms**: Extensive use of C++ Standard Library containers (e.g., `std::vector`, `std::string`, `std::unordered_set`) and algorithms improves development efficiency and code robustness. - **Chrono Library**: Uses the `` library to handle time points (`std::chrono::system_clock::time_point`) for accurately recording when transactions occur.