Giao diện CLI dành cho quản trị viê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 103 trên 107.
Thử thách
DễHãy xây dựng giao diện dòng lệnh cho Hệ thống quản lý thư viện bằng mẫu thiết kế Command! Bạn sẽ tạo một CLI để xử lý các lệnh quản trị như thêm sách, đăng ký người dùng và quản lý việc mượn sách, tất cả thông qua một kiến trúc rõ ràng, dễ mở rộng.
Bạn sẽ tổ chức code trong sáu tệp:
book.go: StructBookcó các thẻ JSON choID,Title,Author,ISBNvàAvailable. Thêm hàm khởi tạoNewBook.user.go: StructUsercó các thẻ JSON choID,Name,EmailvàBorrowedBooks. Thêm hàm khởi tạoNewUser.library.go: StructLibrarycó các map lưu sách và người dùng, cùng với các phương thứcAddBook,AddUser,BorrowvàReturntừ các bài học trước.commands.go: Đây là nơi mẫu thiết kế Command phát huy tác dụng! Định nghĩa một interfaceCommandvới phương thứcExecute, nhận một*Libraryvà các đối số[]string, rồi trả về kết quả dạng chuỗi. Sau đó, triển khai các struct lệnh sau:AddBookCommand: cần 4 đối số: id, title, author, isbn. Thêm sách và trả vềBook added: [title]AddUserCommand: cần 3 đối số: id, name, email. Thêm người dùng và trả vềUser added: [name]BorrowCommand: cần 2 đối số: userID, bookID. Trả vềBorrowed: [bookID]nếu thành công, hoặcError: [message]nếu thất bạiReturnCommand: cần 2 đối số: userID, bookID. Trả vềReturned: [bookID]nếu thành công, hoặcError: [message]nếu thất bạiListBooksCommand: không nhận đối số. Trả về ID và tiêu đề của từng cuốn sách trên các dòng riêng, theo định dạng[id]: [title], hoặcNo booksnếu danh sách trống (sắp xếp sách theo ID)
Nếu một lệnh nhận không đủ đối số, hãy trả về
Error: insufficient argumentscli.go: Tạo một structCLIchứa con trỏ đến mộtLibraryvà map ánh xạ tên lệnh đến các triển khai củaCommand. Tạo:- Hàm khởi tạo
NewCLI, khởi tạo CLI với một thư viện và đăng ký tất cả lệnh:addbook,adduser,borrow,return,listbooks - Phương thức
Runnhận một chuỗi đầu vào, phân tích chuỗi bằngstrings.Fields, tra cứu lệnh và thực thi lệnh đó. Trả vềNo command providednếu đầu vào trống, hoặcUnknown command: [name]nếu lệnh không được nhận diện
- Hàm khởi tạo
main.go: Tạo một thư viện và CLI, sau đó xử lý các lệnh từ đầu vào. Đọc số lượng lệnh, rồi đọc từng chuỗi lệnh trên một dòng riêng. Với mỗi lệnh, gọiRunvà in kết quả.
Đầu vào sẽ gồm:
- Số lượng lệnh
- Mỗi lệnh là một chuỗi hoàn chỉnh trên một dòng riêng
Ví dụ, với đầu vào:
6
addbook B001 Go-Programming Alan-Donovan 978-0134190440
addbook B002 Clean-Code Robert-Martin 978-0132350884
adduser U001 Alice alice@test.com
borrow U001 B001
listbooks
borrow U001 B001Đầu ra sẽ là:
Book added: Go-Programming
Book added: Clean-Code
User added: Alice
Borrowed: B001
B001: Go-Programming
B002: Clean-Code
Error: book not availableVới đầu vào:
4
listbooks
addbook B100 Design-Patterns Gang-of-Four 978-0201633610
listbooks
invalidcmd testĐầu ra sẽ là:
No books
Book added: Design-Patterns
B100: Design-Patterns
Unknown command: invalidcmdVới đầu vào:
5
adduser U001 Bob bob@email.com
borrow U001 B001
addbook B001 Golang-Guide John-Smith 123-456
borrow U001 B001
return U001 B001Đầu ra sẽ là:
User added: Bob
Error: book not found
Book added: Golang-Guide
Borrowed: B001
Returned: B001Bạn có thể thấy CLI không cần biết chi tiết của từng thao tác. CLI chỉ cần tra cứu lệnh rồi chuyển việc thực thi cho lệnh đó. Nhờ vậy, bạn có thể thêm lệnh mới dễ dàng bằng cách tạo một struct mới triển khai interface Command và đăng ký struct đó trong CLI!
Tự làm thử
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// Đọc số lượng lệnh
var n int
fmt.Scanln(&n)
// Tạo scanner để đọc từng dòng đầy đủ
scanner := bufio.NewScanner(os.Stdin)
// TODO: Tạo một Library mới
// TODO: Tạo một CLI mới với thư viện
// TODO: Xử lý từng lệnh
// Với mỗi lệnh trong n lệnh:
// Đọc dòng lệnh bằng scanner.Scan() và scanner.Text()
// Chạy lệnh qua CLI
// In ra kết quả
_ = scanner // Xóa dòng này khi bạn sử dụng scanner
}
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