Struct về sách và người dùng
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 99 trên 107.
Thử thách
DễHãy xây dựng các mô hình dữ liệu cốt lõi cho hệ thống quản lý thư viện! Bạn sẽ tạo các struct nền tảng đại diện cho sách và thành viên thư viện, cùng các hàm khởi tạo (constructor) để khởi tạo chúng với giá trị mặc định hợp lý.
Bạn sẽ sắp xếp code trong ba tệp:
book.go: Định nghĩa structBookvới các trườngID,Title,Author,ISBNvàAvailable(kiểu boolean). Tạo hàm khởi tạoNewBook, nhận ID, tên sách, tác giả và ISBN làm tham số, rồi trả về con trỏ đến một Book mới. Sách mới luôn phải bắt đầu ở trạng thái có sẵn. Thêm phương thứcInfo()trả về thông tin sách theo định dạng:[ID] "Title" by Author (ISBN: [isbn]) - Available: [true/false]user.go: Định nghĩa structUservới các trườngID,Name,EmailvàBorrowedBooks(một slice chuỗi để lưu ID sách). Tạo hàm khởi tạoNewUser, nhận ID, tên và email, rồi trả về con trỏ đến một User mới có danh sách sách đã mượn trống. Thêm phương thứcInfo()trả về:Member: [Name] ([Email]) - Books borrowed: [count]main.go: Kết hợp các mô hình bằng cách tạo sách và người dùng từ đầu vào, sau đó hiển thị thông tin của họ.Đọc số lượng sách, sau đó đọc ID, tên sách, tác giả và ISBN của từng cuốn sách trên các dòng riêng biệt. Tiếp theo, đọc số lượng người dùng, rồi đọc ID, tên và email của từng người dùng trên các dòng riêng biệt.
In thông tin của mỗi cuốn sách trên một dòng riêng, sau đó in thông tin của mỗi người dùng trên một dòng riêng.
Đầu vào sẽ có dạng sau:
- Số lượng sách
- Với mỗi cuốn sách: ID, tên sách, tác giả, ISBN (mỗi mục trên một dòng riêng)
- Số lượng người dùng
- Với mỗi người dùng: ID, tên, email (mỗi mục trên một dòng riêng)
Ví dụ, với đầu vào:
2
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Clean Code
Robert Martin
978-0132350884
1
U001
Alice Smith
alice@library.comĐầu ra của bạn sẽ là:
[B001] "The Go Programming Language" by Alan Donovan (ISBN: 978-0134190440) - Available: true
[B002] "Clean Code" by Robert Martin (ISBN: 978-0132350884) - Available: true
Member: Alice Smith (alice@library.com) - Books borrowed: 0Với đầu vào:
1
B100
Design Patterns
Gang of Four
978-0201633610
2
U001
Bob Jones
bob@email.com
U002
Carol White
carol@email.comĐầu ra của bạn sẽ là:
[B100] "Design Patterns" by Gang of Four (ISBN: 978-0201633610) - Available: true
Member: Bob Jones (bob@email.com) - Books borrowed: 0
Member: Carol White (carol@email.com) - Books borrowed: 0Hãy chú ý cách các hàm khởi tạo xử lý giá trị mặc định: sách bắt đầu ở trạng thái có sẵn và người dùng bắt đầu với không cuốn sách nào đã mượn. Việc dùng hàm khởi tạo để đảm bảo khởi tạo đúng cách là một nguyên tắc nền tảng khi xây dựng các hệ thống đáng tin cậy!
Tự làm thử
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Đọc số lượng sách
numBooksStr, _ := reader.ReadString('\n')
numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))
// TODO: Tạo một slice để lưu sách
// Đọc thông tin chi tiết của từng cuốn sách
for i := 0; i < numBooks; i++ {
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
title, _ := reader.ReadString('\n')
title = strings.TrimSpace(title)
author, _ := reader.ReadString('\n')
author = strings.TrimSpace(author)
isbn, _ := reader.ReadString('\n')
isbn = strings.TrimSpace(isbn)
// TODO: Dùng hàm khởi tạo NewBook để tạo sách mới rồi thêm vào slice
}
// Đọc số lượng người dùng
numUsersStr, _ := reader.ReadString('\n')
numUsers, _ := strconv.Atoi(strings.TrimSpace(numUsersStr))
// TODO: Tạo một slice để lưu người dùng
// Đọc thông tin chi tiết của từng người dùng
for i := 0; i < numUsers; i++ {
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
email, _ := reader.ReadString('\n')
email = strings.TrimSpace(email)
// TODO: Dùng hàm khởi tạo NewUser để tạo người dùng mới rồi thêm vào slice
}
// TODO: Dùng phương thức Info() để in ra thông tin của từng cuốn sách
// TODO: Dùng phương thức Info() để in ra thông tin của từng người dùng
fmt.Println() // Dòng tạm, xóa khi triển khai
}
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 pool12Các khái niệm OOP nâng cao
Mẫu tùy chọn hàmMẫu Builder trong GoChuỗi phương thứcBí danh kiểu dữ liệu và định nghĩa kiểuCơ bản về reflectionTổng quan về tạo code15Dự án: Quản lý thư viện
Tổng quan và cấu trúc dự ánStruct về sách và người dùngTự luyện tập: Trình biên dịch Go online