Menu
CoddyTech

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.

challenge icon

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: Struct Book có các thẻ JSON cho ID, Title, Author, ISBN và Available. Thêm hàm khởi tạo NewBook.
  • user.go: Struct User có các thẻ JSON cho ID, Name, Email và BorrowedBooks. Thêm hàm khởi tạo NewUser.
  • library.go: Struct Library có các map lưu sách và người dùng, cùng với các phương thức AddBook, AddUser, Borrow và Return từ 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 interface Command với phương thức Execute, nhận một *Library và 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ặc Error: [message] nếu thất bại
    • ReturnCommand: cần 2 đối số: userID, bookID. Trả về Returned: [bookID] nếu thành công, hoặc Error: [message] nếu thất bại
    • ListBooksCommand: 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ặc No books nế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 arguments

  • cli.go: Tạo một struct CLI chứa con trỏ đến một Library và map ánh xạ tên lệnh đến các triển khai của Command. 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 Run nhận một chuỗi đầu vào, phân tích chuỗi bằng strings.Fields, tra cứu lệnh và thực thi lệnh đó. Trả về No command provided nếu đầu vào trống, hoặc Unknown command: [name] nếu lệnh không được nhận diện
  • 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ọi Run và 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 available

Vớ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: invalidcmd

Vớ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: B001

Bạ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

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