Ôn tập: bộ xử lý thanh toán
Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 46 trên 107.
Thử thách
DễHãy cùng xây dựng một hệ thống xử lý thanh toán hoàn chỉnh, kết hợp tất cả các khái niệm về đa hình trong chương này. Bạn sẽ tạo các phương thức thanh toán khác nhau hoạt động thông qua một giao diện thống nhất, một bộ xử lý chấp nhận mọi phương thức thanh toán thông qua cơ chế tiêm phụ thuộc và xử lý nhiều khoản thanh toán thông qua một tập hợp đa hình.
Bạn sẽ tổ chức code trong bốn tệp:
payment.go: Định nghĩa giao diệnPaymentMethod, yêu cầu một phương thứcProcess(amount float64) string. Đây là hợp đồng mà tất cả các kiểu thanh toán phải tuân theo.methods.go: Tạo ba kiểu thanh toán, mỗi kiểu đều triển khai giao diệnPaymentMethod:CreditCardcó các trườngCardNumber(chuỗi) vàHolderName(chuỗi). Phương thứcProcesstrả vềCredit Card [last 4 digits of CardNumber] charged $[amount] to [HolderName]PayPalcó trườngEmail. Phương thứcProcesstrả vềPayPal payment of $[amount] from [Email]BankTransfercó các trườngBankNamevàAccountNumber. Phương thứcProcesstrả vềBank transfer of $[amount] via [BankName] (***[last 3 digits of AccountNumber])
processor.go: Tạo cấu trúcPaymentProcessorlưu mộtPaymentMethod(phụ thuộc được tiêm vào). Thêm hàm khởi tạoNewPaymentProcessornhận mộtPaymentMethod. Thêm phương thứcExecutePayment(amount float64) stringđể ủy quyền xử lý cho phương thức thanh toán được tiêm vào. Đồng thời tạo hàmProcessAll(payments []PaymentMethod, amount float64) []string, xử lý cùng một số tiền bằng từng phương thức thanh toán trong lát cắt và trả về tất cả kết quả.main.go: Đọc thông tin thanh toán từ đầu vào, tạo cả ba kiểu thanh toán và minh họa cả cơ chế tiêm phụ thuộc lẫn các tập hợp đa hình. Trước tiên, dùngNewPaymentProcessorvới thẻ tín dụng rồi thực hiện một khoản thanh toán. Sau đó, gom cả ba phương thức thanh toán vào một lát cắt và dùngProcessAllđể xử lý tất cả với số tiền thứ hai. In từng kết quả trên một dòng riêng.
Đầu vào sẽ có dạng sau:
- Dòng 1: Số thẻ tín dụng (ví dụ:
4532015112830366) - Dòng 2: Tên chủ thẻ
- Dòng 3: Email PayPal
- Dòng 4: Tên ngân hàng
- Dòng 5: Số tài khoản (ví dụ:
987654321) - Dòng 6: Số tiền thanh toán thứ nhất (cho bộ xử lý đơn lẻ)
- Dòng 7: Số tiền thanh toán thứ hai (cho xử lý hàng loạt)
Định dạng số tiền với hai chữ số thập phân. Ví dụ, với 4532015112830366, John Smith, john@email.com, Chase, 987654321, 99.99 và 50, đầu ra sẽ là:
Credit Card 0366 charged $99.99 to John Smith
Credit Card 0366 charged $50.00 to John Smith
PayPal payment of $50.00 from john@email.com
Bank transfer of $50.00 via Chase (***321)Dòng đầu tiên hiển thị khoản thanh toán đơn lẻ thông qua bộ xử lý được tiêm phụ thuộc. Ba dòng còn lại hiển thị kết quả xử lý hàng loạt thông qua tập hợp đa hình: cùng một hàm ProcessAll xử lý đồng nhất tất cả các kiểu thanh toán, minh họa cách giao diện giúp hệ thống thanh toán linh hoạt và dễ mở rộng.
Tự làm thử
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Đọc đầu vào
cardNumber, _ := reader.ReadString('\n')
cardNumber = strings.TrimSpace(cardNumber)
holderName, _ := reader.ReadString('\n')
holderName = strings.TrimSpace(holderName)
email, _ := reader.ReadString('\n')
email = strings.TrimSpace(email)
bankName, _ := reader.ReadString('\n')
bankName = strings.TrimSpace(bankName)
accountNumber, _ := reader.ReadString('\n')
accountNumber = strings.TrimSpace(accountNumber)
amount1Str, _ := reader.ReadString('\n')
amount1Str = strings.TrimSpace(amount1Str)
amount1, _ := strconv.ParseFloat(amount1Str, 64)
amount2Str, _ := reader.ReadString('\n')
amount2Str = strings.TrimSpace(amount2Str)
amount2, _ := strconv.ParseFloat(amount2Str, 64)
// TODO: Tạo ba kiểu thanh toán (CreditCard, PayPal, BankTransfer)
// TODO: Dùng NewPaymentProcessor để tạo PaymentProcessor với thẻ tín dụng
// và thực hiện thanh toán với amount1, rồi in ra kết quả
// TODO: Tạo một slice gồm cả ba kiểu thanh toán PaymentMethod
// TODO: Dùng ProcessAll để xử lý mọi khoản thanh toán với amount2
// và in mỗi kết quả trên một dòng riêng
}
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng OOP trong Go
Tệp bên ngoàiWorkspace và module trong GoPackage và importTên được export và không được exportGiới thiệu về OOP trong GoStruct như lớpĐịnh nghĩa phương thức cho structReceiver kiểu con trỏ và kiểu giá trịKhởi tạo structHàm khởi tạoÔn tập: máy tính đơn giản4Interface
Giới thiệu về interfaceTriển khai ngầm địnhInterface như một hợp đồngInterface rỗng (any)Khẳng định kiểuswitch kiểuKết hợp interfaceInterface Stringer và ErrorÔn tập: Máy tính hình học7Tính đóng gói
Trường được xuất và không được xuấtĐóng gói ở cấp packagePhương thức getter và setterẨn thông tin trong GoÔn tập: hồ sơ học sinh10Generics (Go 1.18 trở lên)
Giới thiệu về GenericsTham số kiểuRàng buộc kiểuStruct tổng quátGiải pháp thay thế cho phương thức tổng quátÔn tập: tập hợp tổng quát13Các mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếMẫu SingletonMẫu FactoryMẫu Abstract FactoryMẫu ObserverMẫu Strategy2Tìm hiểu chuyên sâu về kiểu dữ liệu và struct
Kiểu cơ bản và kiểu tổng hợpĐịnh nghĩa kiểu dữ liệu tùy chỉnhThẻ structStruct ẩn danhStruct lồng nhauGiá trị zero và giá trị mặc địnhÔn tập: sổ liên lạc5Ưu tiên kết hợp hơn kế thừa
Vì sao Go không có kế thừaNhập môn nhúng structTự động nâng phương thứcNhúng nhiều structNhúng và kết tậpChe khuất phương thức được nhúngÔn tập: hệ phân cấp nhân viên8Xử lý lỗi và lập trình hướng đối tượng
Giao diện errorCác kiểu lỗi tùy chỉnhBọc lỗi với fmt.ErrorfLỗi sentinelerrors.Is() và errors.As()Panic, defer và recoverÔn tập: trình phân tích tệp3Con trỏ và bộ nhớ
Cơ bản về con trỏ trong GoCon trỏ đến structTruyền theo giá trị và tham chiếuHàm new()Thu gom rác trong GoÔn tập: xây dựng danh sách liên kết6Đa hình trong Go
Đa hình qua interfaceĐịnh kiểu vịt trong GoQuy tắc thỏa mãn interfaceCác tập hợp đa hìnhTiêm phụ thuộcÔn tập: bộ xử lý thanh toán9Lập trình đồng thời và lập trình hướng đối tượng
Cơ bản về goroutineChannel và giao tiếpChannel có bộ đệm và không có bộ đệmCâu lệnh selectsync.Mutex và sync.RWMutexsync.WaitGroupThiết kế struct an toàn luồngÔn tập: worker poolTự luyện tập: Trình biên dịch Go online