Interface CLI de administração
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 103 de 107.
Desafio
FácilVamos criar uma interface de linha de comando para o nosso Sistema de Gerenciamento de Biblioteca usando o Padrão de Comando! Você criará uma CLI que processa comandos administrativos, como adicionar livros, cadastrar usuários e gerenciar operações de empréstimo — tudo por meio de uma arquitetura limpa e extensível.
Você organizará seu código em seis arquivos:
book.go: sua structBookcom tags JSON paraID,Title,Author,ISBNeAvailable. Inclua o construtorNewBook.user.go: sua structUsercom tags JSON paraID,Name,EmaileBorrowedBooks. Inclua o construtorNewUser.library.go: sua structLibrarycom mapas para livros e usuários, juntamente com os métodosAddBook,AddUser,BorroweReturndas lições anteriores.commands.go: é aqui que o Padrão de Comando ganha vida! Defina uma interfaceCommandcom um métodoExecuteque receba um*Librarye argumentos[]string, retornando um resultado do tipo string. Em seguida, implemente estas structs de comando:AddBookCommand: espera 4 argumentos: id, title, author, isbn. Adiciona o livro e retornaBook added: [title]AddUserCommand: espera 3 argumentos: id, name, email. Adiciona o usuário e retornaUser added: [name]BorrowCommand: espera 2 argumentos: userID, bookID. RetornaBorrowed: [bookID]em caso de sucesso ouError: [message]em caso de falhaReturnCommand: espera 2 argumentos: userID, bookID. RetornaReturned: [bookID]em caso de sucesso ouError: [message]em caso de falhaListBooksCommand: não recebe argumentos. Retorna o ID e o título de cada livro em linhas separadas, no formato[id]: [title], ouNo booksse estiver vazio (liste os livros ordenados por ID)
Se um comando receber argumentos insuficientes, retorne
Error: insufficient argumentscli.go: crie uma structCLIque contenha um ponteiro para umaLibrarye um mapa de nomes de comandos para implementações deCommand. Crie:- o construtor
NewCLI, que inicializa a CLI com uma biblioteca e registra todos os comandos:addbook,adduser,borrow,return,listbooks - o método
Run, que recebe uma string de entrada, analisa-a usandostrings.Fields, procura o comando e o executa. RetorneNo command providedpara uma entrada vazia ouUnknown command: [name]para comandos não reconhecidos
- o construtor
main.go: crie uma biblioteca e uma CLI e, em seguida, processe os comandos da entrada. Leia o número de comandos e depois leia cada string de comando em uma linha separada. Para cada comando, chameRune imprima o resultado.
As seguintes entradas serão fornecidas:
- Número de comandos
- Cada comando como uma string completa em sua própria linha
Por exemplo, dada a entrada:
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 B001Sua saída deverá ser:
Book added: Go-Programming
Book added: Clean-Code
User added: Alice
Borrowed: B001
B001: Go-Programming
B002: Clean-Code
Error: book not availableE, dada a entrada:
4
listbooks
addbook B100 Design-Patterns Gang-of-Four 978-0201633610
listbooks
invalidcmd testSua saída deverá ser:
No books
Book added: Design-Patterns
B100: Design-Patterns
Unknown command: invalidcmdE, dada a entrada:
5
adduser U001 Bob bob@email.com
borrow U001 B001
addbook B001 Golang-Guide John-Smith 123-456
borrow U001 B001
return U001 B001Sua saída deverá ser:
User added: Bob
Error: book not found
Book added: Golang-Guide
Borrowed: B001
Returned: B001Observe como a CLI não precisa conhecer os detalhes de cada operação. Ela simplesmente procura o comando e delega a execução. Isso torna a adição de novos comandos tão simples quanto criar uma nova struct que implemente a interface Command e registrá-la na CLI!
Experimente você mesmo
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// Lê o número de comandos
var n int
fmt.Scanln(&n)
// Cria um scanner para ler linhas completas
scanner := bufio.NewScanner(os.Stdin)
// TODO: Cria uma nova Library
// TODO: Cria um novo CLI com a library
// TODO: Processa cada comando
// Para cada um dos n comandos:
// - Lê a linha de comando usando scanner.Scan() e scanner.Text()
// - Executa o comando através do CLI
// - Imprime o resultado
_ = scanner // Remova esta linha quando você usar o scanner
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosWorkspace e Módulos do GoPacotes e ImportsNomes Exportados vs. Não ExportadosIntrodução à OOP em GoStructs como ClassesDefinindo Métodos em StructsReceptores de Ponteiro vs. de ValorInicialização de StructsFunções ConstrutorasRecapitulação — Calculadora Simples4Interfaces
Introdução às InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Asserção de TipoSwitch de TipoComposição de InterfacesInterfaces Stringer e ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs. Não ExportadosEncapsulamento no Nível de PacoteMétodos Getters e SettersOcultação de Informações em GoRecapitulação - Registros de Alunos10Genéricos (Go 1.18+)
Introdução aos genéricosParâmetros de tipoRestrições de tipoStructs genéricasAlternativa para métodos genéricosRecapitulação - Coleção genérica13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão Abstract FactoryPadrão ObserverPadrão Strategy2Tipos e Structs em Profundidade
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosTags de StructStructs AnônimasStructs AninhadasValores Zero e PadrõesRecapitulação - Livro de Contatos5Composição em vez de herança
Por que Go não tem herançaNoções básicas de incorporação de structsPromoção de métodosIncorporação de várias structsIncorporação vs agregaçãoOcultação de métodos incorporadosRecapitulação - Hierarquia de funcionários8Tratamento de Erros e OOP
A interface errorTipos de Erro PersonalizadosEncapsulamento de Erros (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - Analisador de Arquivos3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs. ReferênciaA Função new()Coleta de Lixo em GoRecapitulação - Construtor de Lista Ligada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfacesColeções PolimórficasInjeção de DependênciasRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e comunicaçãoCanais com e sem bufferInstrução selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de structs thread-safeRevisão - Worker Pool12Conceitos Avançados de OOP
Padrão de Opções FuncionaisPadrão Builder em GoEncadeamento de MétodosAliases de Tipos vs. DefiniçõesNoções Básicas de ReflectionVisão Geral da Geração de Código15Projeto: Gerenciamento de Biblioteca
Visão geral e estrutura do projetoStructs de livros e usuáriosPratique por conta própria: Compilador de Go online