Menu
Coddy logo textTech

Interfaz CLI de administración

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 103 de 107.

challenge icon

Desafío

Fácil

¡Vamos a construir una interfaz de línea de comandos para nuestro Sistema de Gestión de Biblioteca utilizando el Patrón Command! Crearás una CLI que procesa comandos de administrador como añadir libros, registrar usuarios y gestionar operaciones de préstamo, todo a través de una arquitectura limpia y extensible.

Organizarás tu código en seis archivos:

  • book.go: Tu struct Book con etiquetas JSON para ID, Title, Author, ISBN y Available. Incluye el constructor NewBook.
  • user.go: Tu struct User con etiquetas JSON para ID, Name, Email y BorrowedBooks. Incluye el constructor NewUser.
  • library.go: Tu struct Library con mapas para libros y usuarios, junto con los métodos AddBook, AddUser, Borrow y Return de lecciones anteriores.
  • commands.go: ¡Aquí es donde el Patrón Command cobra vida! Define una interfaz Command con un método Execute que recibe un *Library y argumentos []string, devolviendo un resultado de tipo string. Luego implementa estos structs de comando:
    • AddBookCommand — espera 4 argumentos: id, title, author, isbn. Añade el libro y devuelve Book added: [title]
    • AddUserCommand — espera 3 argumentos: id, name, email. Añade al usuario y devuelve User added: [name]
    • BorrowCommand — espera 2 argumentos: userID, bookID. Devuelve Borrowed: [bookID] en caso de éxito, o Error: [message] en caso de fallo
    • ReturnCommand — espera 2 argumentos: userID, bookID. Devuelve Returned: [bookID] en caso de éxito, o Error: [message] en caso de fallo
    • ListBooksCommand — no recibe argumentos. Devuelve el ID y el título de cada libro en líneas separadas con el formato [id]: [title], o No books si está vacío (lista los libros ordenados por ID)

    Si un comando recibe argumentos insuficientes, devuelve Error: insufficient arguments

  • cli.go: Crea un struct CLI que contenga un puntero a una Library y un mapa de nombres de comandos a implementaciones de Command. Construye:
    • El constructor NewCLI que inicializa la CLI con una biblioteca y registra todos los comandos: addbook, adduser, borrow, return, listbooks
    • El método Run que recibe una cadena de entrada, la analiza usando strings.Fields, busca el comando y lo ejecuta. Devuelve No command provided para una entrada vacía, o Unknown command: [name] para comandos no reconocidos
  • main.go: Crea una biblioteca y una CLI, luego procesa los comandos de la entrada. Lee el número de comandos, luego lee cada cadena de comando en una línea separada. Para cada comando, llama a Run e imprime el resultado.

Se proporcionarán las siguientes entradas:

  • Número de comandos
  • Cada comando como una cadena completa en su propia línea

Por ejemplo, dado:

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

Tu salida debería ser:

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

Y dado:

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

Tu salida debería ser:

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

Y dado:

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

Tu salida debería ser:

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

Observa cómo la CLI no necesita conocer los detalles de cada operación; simplemente busca el comando y delega la ejecución. ¡Esto hace que añadir nuevos comandos sea tan sencillo como crear un nuevo struct que implemente la interfaz Command y registrarlo en la CLI!

Pruébalo tú mismo

package main

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

func main() {
	// Lee el número de comandos
	var n int
	fmt.Scanln(&n)

	// Crea un scanner para leer líneas completas
	scanner := bufio.NewScanner(os.Stdin)

	// TODO: Crea una nueva Library

	// TODO: Crea un nuevo CLI con la biblioteca

	// TODO: Procesa cada comando
	// Para cada uno de los n comandos:
	// - Lee la línea de comando usando scanner.Scan() y scanner.Text()
	// - Ejecuta el comando a través del CLI
	// - Imprime el resultado

	_ = scanner // Elimina esta línea cuando uses scanner
}

Todas las lecciones de Programación Orientada a Objetos