Menu
CoddyTech

管理员 CLI 界面

本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 103 课,共 107 课。

challenge icon

挑战

简单

让我们使用命令模式,为图书馆管理系统构建一个命令行界面!你将创建一个 CLI,用来处理管理员命令,例如添加图书、注册用户和管理借阅操作,所有这些都通过清晰且易于扩展的架构完成。

你需要将代码分成 6 个文件:

  • book.go:定义 Book 结构体,并为 ID、Title、Author、ISBN 和 Available 添加 JSON 标签。还要包含 NewBook 构造函数。
  • user.go:定义 User 结构体,并为 ID、Name、Email 和 BorrowedBooks 添加 JSON 标签。还要包含 NewUser 构造函数。
  • library.go:定义 Library 结构体,其中包含用于存放图书和用户的映射,以及前几课中的 AddBook、AddUser、Borrow 和 Return 方法。
  • commands.go:在这里实现命令模式!定义一个 Command 接口,其中包含 Execute 方法。该方法接收一个 *Library 和 []string 参数,并返回字符串结果。然后实现以下命令结构体:
    • AddBookCommand:需要 4 个参数:id、title、author、isbn。添加图书,并返回 Book added: [title]
    • AddUserCommand:需要 3 个参数:id、name、email。添加用户,并返回 User added: [name]
    • BorrowCommand:需要 2 个参数:userID、bookID。成功时返回 Borrowed: [bookID],失败时返回 Error: [message]
    • ReturnCommand:需要 2 个参数:userID、bookID。成功时返回 Returned: [bookID],失败时返回 Error: [message]
    • ListBooksCommand:不需要参数。按图书 ID 排序,并逐行返回每本图书的 ID 和标题,格式为 [id]: [title];如果没有图书,则返回 No books

    如果命令收到的参数不足,则返回 Error: insufficient arguments

  • cli.go:创建一个 CLI 结构体,其中保存指向 Library 的指针,以及命令名称到 Command 实现的映射。实现以下内容:
    • NewCLI 构造函数:使用一个图书馆初始化 CLI,并注册所有命令:addbook、adduser、borrow、return、listbooks
    • Run 方法:接收一个输入字符串,使用 strings.Fields 解析字符串,查找命令并执行。输入为空时返回 No command provided;遇到无法识别的命令时,返回 Unknown command: [name]
  • main.go:创建图书馆和 CLI,然后处理输入中的命令。读取命令数量,再逐行读取每条命令字符串。对于每条命令,调用 Run 并打印结果。

输入将包含以下内容:

  • 命令数量
  • 每条命令都是单独一行上的完整字符串

例如,给定:

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

你的输出应为:

Book added: Go-Programming
Book added: Clean-Code
User added: Alice
Borrowed: B001
B001: Go-Programming
B002: Clean-Code
Error: book not available

再比如,给定:

4
listbooks
addbook B100 Design-Patterns Gang-of-Four 978-0201633610
listbooks
invalidcmd test

你的输出应为:

No books
Book added: Design-Patterns
B100: Design-Patterns
Unknown command: invalidcmd

再比如,给定:

5
adduser U001 Bob bob@email.com
borrow U001 B001
addbook B001 Golang-Guide John-Smith 123-456
borrow U001 B001
return U001 B001

你的输出应为:

User added: Bob
Error: book not found
Book added: Golang-Guide
Borrowed: B001
Returned: B001

注意,CLI 不需要了解每种操作的具体细节。它只需查找命令并委托执行即可。要添加新命令,只需创建一个实现 Command 接口的新结构体,并在 CLI 中注册它!

亲手试试

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 读取命令的数量
	var n int
	fmt.Scanln(&n)

	// 创建一个 scanner,用于读取完整的行
	scanner := bufio.NewScanner(os.Stdin)

	// TODO: 创建一个新的 Library

	// TODO: 使用这个库创建一个新的 CLI

	// TODO: 处理每条命令
	// 对于这 n 条命令中的每一条:
	// - 使用 scanner.Scan() 和 scanner.Text() 读取命令行
	// - 通过 CLI 运行命令
	// - 打印结果

	_ = scanner // 使用 scanner 时删除这一行
}

面向对象编程中的所有课

自己练习: Go 在线编译器