Menu
CoddyTech

Ô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.

challenge icon

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ện PaymentMethod, yêu cầu một phương thức Process(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ện PaymentMethod:
    • CreditCard có các trường CardNumber (chuỗi) và HolderName (chuỗi). Phương thức Process trả về Credit Card [last 4 digits of CardNumber] charged $[amount] to [HolderName]
    • PayPal có trường Email. Phương thức Process trả về PayPal payment of $[amount] from [Email]
    • BankTransfer có các trường BankName và AccountNumber. Phương thức Process trả về Bank transfer of $[amount] via [BankName] (***[last 3 digits of AccountNumber])
  • processor.go: Tạo cấu trúc PaymentProcessor lưu một PaymentMethod (phụ thuộc được tiêm vào). Thêm hàm khởi tạo NewPaymentProcessor nhận một PaymentMethod. Thêm phương thức ExecutePayment(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àm ProcessAll(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ùng NewPaymentProcessor vớ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ùng ProcessAll để 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

Tự luyện tập: Trình biên dịch Go online