Hệ thống ngân hàng
Thuộc phần Lập trình hướng đối tượng trong hành trình C++ của Coddy. Bài học 104 trên 104.
Thử thách
DễHãy xây dựng một hệ thống ngân hàng minh họa mẫu State, tính kế thừa và cách quản lý con trỏ thông minh. Bạn sẽ tạo một hệ thống trong đó các tài khoản có thể ở những trạng thái khác nhau (Active, Frozen, Closed), mỗi trạng thái có cách xử lý giao dịch riêng.
Bạn sẽ sắp xếp code trong sáu tệp:
AccountState.h: Xây dựng cơ sở hạ tầng cho mẫu State để quản lý các trạng thái tài khoản.Tạo một lớp cơ sở trừu tượng
AccountStatevới các phương thức thuần ảo:deposit(double amount): trả về true nếu cho phép gửi tiền, nếu không thì trả về falsewithdraw(double amount): trả về true nếu cho phép rút tiền, nếu không thì trả về falsegetStateName(): trả về tên trạng thái dưới dạng chuỗi
Triển khai ba trạng thái cụ thể:
ActiveState: Cho phép gửi và rút tiền, trả về"Active"FrozenState: Cho phép gửi tiền nhưng từ chối rút tiền, trả về"Frozen"ClosedState: Từ chối cả gửi lẫn rút tiền, trả về"Closed"
Account.h: Xây dựng hệ thống phân cấp tài khoản có quản lý trạng thái.Tạo lớp cơ sở
Accountgồm:- Số tài khoản (chuỗi), tên chủ tài khoản và số dư
- Một
std::unique_ptr<AccountState>để quản lý trạng thái hiện tại deposit(double amount): trước tiên kiểm tra trạng thái; nếu được phép thì cộng vào số dư và in ra"Deposited [amount] to [accountNumber]", nếu không thì in ra"Deposit rejected: account is [stateName]"withdraw(double amount): kiểm tra trạng thái; nếu được phép và đủ tiền thì trừ tiền và in ra"Withdrew [amount] from [accountNumber]". Nếu trạng thái từ chối, hãy in ra"Withdrawal rejected: account is [stateName]". Nếu không đủ tiền, hãy in ra"Insufficient funds"freeze(),activate()vàclose(): thay đổi trạng thái tài khoảngetInfo(): trả về"[accountNumber] ([ownerName]): $[balance] - [stateName]"getAccountType()ảo, trả về"Basic"
Tạo hai kiểu tài khoản dẫn xuất:
SavingsAccount: Có yêu cầu số dư tối thiểu (truyền vào hàm khởi tạo). Ghi đè withdraw để kiểm tra thêm xem việc rút tiền có làm số dư thấp hơn mức tối thiểu hay không; nếu có, hãy in ra"Cannot go below minimum balance of [minimum]". Trả về"Savings"cho kiểu tài khoản.CheckingAccount: Có hạn mức thấu chi (truyền vào hàm khởi tạo). Cho phép rút tiền tối đa bằng (số dư + overdraftLimit). Trả về"Checking"cho kiểu tài khoản.
Transaction.h: Mô hình hóa giao dịch thành các đối tượng.Tạo lớp
Transactionđể ghi lại:- Loại giao dịch (chuỗi: "Deposit", "Withdrawal", "Transfer")
- Số tiền
- Số tài khoản liên quan
- Trạng thái thành công (bool)
Thêm phương thức
getDescription()trả về"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: Tạo một khách hàng sở hữu nhiều tài khoản.Một
Customercó tên, ID và một vector gồm cácstd::shared_ptr<Account>. Triển khai:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber): trả về tài khoản khớp hoặc nullptrgetTotalBalance(): tính tổng số dư của tất cả tài khoảnlistAccounts(): in thông tin của từng tài khoản
Bank.h: Điều phối các hoạt động ngân hàng.Lớp
Banklưu trữ khách hàng và duy trì lịch sử giao dịch. Triển khai:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber): tìm tài khoản trong tất cả khách hàngprocessDeposit(const std::string& accountNumber, double amount): tìm tài khoản, thực hiện gửi tiền và ghi lại giao dịchprocessWithdrawal(const std::string& accountNumber, double amount): tìm tài khoản, thực hiện rút tiền và ghi lại giao dịchgetTransactionCount(): trả về tổng số giao dịch đã xử lý
main.cpp: Minh họa hệ thống ngân hàng của bạn.Đọc bốn đầu vào:
- Thông tin khách hàng (định dạng:
name,customerId) - Thông tin tài khoản tiết kiệm (định dạng:
accountNumber,minBalance) - Thao tác 1 (định dạng:
action,accountNumber,amount, trong đó action làdeposithoặcwithdraw) - Thao tác 2 (định dạng:
action,accountNumber,amounthoặcfreeze,accountNumber)
Tạo ngân hàng và khách hàng. Tạo một tài khoản tiết kiệm với khách hàng làm chủ tài khoản rồi thêm tài khoản đó vào khách hàng. Thêm khách hàng vào ngân hàng. Thực hiện cả hai thao tác (nếu là lệnh freeze, hãy đóng băng tài khoản rồi thử rút một khoản nhỏ là $10 để minh họa trạng thái). Cuối cùng, in danh sách tài khoản của khách hàng và tổng số giao dịch theo định dạng
"Transactions: [count]".- Thông tin khách hàng (định dạng:
Ví dụ, với các đầu vào Alice,C001, SAV001,100, deposit,SAV001,500 và withdraw,SAV001,200:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2Với các đầu vào Bob,C002, SAV002,50, deposit,SAV002,100 và freeze,SAV002:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2Với các đầu vào Carol,C003, SAV003,200, deposit,SAV003,250 và withdraw,SAV003,100:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2Thử thách này kết hợp mẫu State để quản lý hành vi tài khoản, tính kế thừa cho các kiểu tài khoản khác nhau, con trỏ thông minh để quản lý quan hệ sở hữu và theo dõi giao dịch: tất cả đều là những khái niệm cốt lõi bạn đã nắm vững trong suốt khóa học này.
Tự làm thử
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// Đọc đầu vào 1: thông tin khách hàng (định dạng: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// Đọc đầu vào 2: thông tin tài khoản tiết kiệm (định dạng: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// Đọc đầu vào 3: thao tác 1 (định dạng: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// Đọc đầu vào 4: thao tác 2 (định dạng: action,accountNumber,amount hoặc freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: Phân tích thông tin khách hàng từ customerInput
// Gợi ý: Dùng find(',') để tách chuỗi
// TODO: Phân tích thông tin tài khoản từ accountInput
// TODO: Tạo ngân hàng
// TODO: Tạo khách hàng
// TODO: Tạo tài khoản tiết kiệm do khách hàng sở hữu
// TODO: Thêm tài khoản cho khách hàng
// TODO: Thêm khách hàng vào ngân hàng
// TODO: Phân tích cú pháp và xử lý thao tác 1
// Định dạng: action,accountNumber,amount (action là "deposit" hoặc "withdraw")
// TODO: Phân tích cú pháp và xử lý thao tác 2
// Có thể là: action,accountNumber,amount hoặc freeze,accountNumber
// Nếu là freeze, đóng băng tài khoản rồi thử rút $10
// TODO: In ra danh sách tài khoản của khách hàng
// TODO: In ra số lượng giao dịch theo dạng "Transactions: [count]"
return 0;
}
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về OOP
Tệp bên ngoàiBiên dịch và tạo bản dựng C++Tệp header và tệp nguồnNamespace và phạm viGiới thiệu về OOP trong C++Lớp và đối tượngCon trỏ thisPhương thức (hàm thành viên)Thuộc tính (dữ liệu thành viên)Cơ bản về hàm khởi tạo và hàm hủyÔn tập: máy tính đơn giản4Thuộc tính của lớp
Thành viên đối tượng và thành viên tĩnhHàm truy xuất và hàm thiết lậpHàm thành viên hằngTừ khóa mutablePhương thức và biến tĩnhHàm và lớp bạnÔn tập: Trình quản lý tài khoản ngân hàng7Kế thừa
Kế thừa cơ bảnMức truy cập trong kế thừaThứ tự gọi hàm khởi tạo và hàm hủyGhi đè phương thứcHàm ảo và VTableĐa kế thừaKế thừa ảoÔn tập: hệ phân cấp nhân viên2Quản lý bộ nhớ
Bộ nhớ ngăn xếp và heapCon trỏ và tham chiếuBộ nhớ động (new/delete)Con trỏ thông minh trong C++RAII trong C++Ôn tập: Trình quản lý mảng động5Tính đóng gói
Phạm vi truy cập trong C++Tìm hiểu sâu về phạm vi truy cậpẨn thông tinStruct và lớpLớp lồng nhau và lớp bên trongÔn tập: hệ thống hồ sơ sinh viên8Đa hình
Đa hình lúc biên dịch và khi chạyNạp chồng hàmÔn lại hàm ảoHàm ảo thuần túyLớp trừu tượngThiết kế interface trong C++Ép kiểu động và RTTIÔn tập: Máy tính hình học3Hàm khởi tạo và hàm hủy
Hàm khởi tạo mặc địnhHàm khởi tạo có tham sốHàm khởi tạo sao chépHàm khởi tạo di chuyểnDanh sách khởi tạoHàm khởi tạo ủy quyềnTìm hiểu sâu về hàm hủyQuy tắc 3 / 5 / 0Ôn tập: lớp chuỗi6Nạp chồng toán tử
Giới thiệu về nạp chồng toán tửNạp chồng toán tử số họcNạp chồng toán tử so sánhToán tử luồngNạp chồng toán tử gánNạp chồng toán tử [] và ()Toán tử chuyển đổi kiểuÔn tập: lớp ma trận9Mẫu
Mẫu hàmMẫu lớpChuyên biệt hóa mẫuMẫu biến tham sốCơ bản về SFINAE và đặc điểm kiểuÔn tập: vùng chứa tổng quátTự luyện tập: Trình biên dịch C++ online