Menu
Coddy logo textTech

Sistema de empréstimos

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 100 de 107.

challenge icon

Desafio

Fácil

Vamos construir o sistema de empréstimos para nosso projeto de gerenciamento de Library! Você criará uma struct Library que gerencia coleções de livros e usuários, com métodos para lidar com operações de retirada e devolução: tudo isso com a validação adequada.

Você organizará seu código em quatro arquivos:

  • book.go: Sua struct Book da lição anterior, com os campos ID, Title, Author, ISBN e Available. Inclua o construtor NewBook, que inicializa os livros como disponíveis.
  • user.go: Sua struct User, com ID, Name, Email e BorrowedBooks (slice de IDs de livros). Inclua o construtor NewUser, que inicializa os usuários com uma lista de empréstimos vazia.
  • library.go: Crie uma struct Library que armazena livros e usuários em mapas (indexados por seus IDs). Crie estes componentes:
    • Um construtor NewLibrary que inicializa mapas vazios para livros e usuários
    • Um método AddBook que adiciona um livro à biblioteca
    • Um método AddUser que adiciona um usuário à biblioteca
    • Um método Borrow que recebe um ID de usuário e um ID de livro, valida a operação, marca o livro como indisponível, adiciona o ID do livro à lista de empréstimos do usuário e retorna um erro se algo der errado
    • Um método Return que reverte o processo de empréstimo: marca o livro como disponível e o remove da lista de empréstimos do usuário

    Seu método Borrow deve retornar estes erros:

    • user not found se o ID do usuário não existir
    • book not found se o ID do livro não existir
    • book not available se o livro já estiver emprestado

    Seu método Return deve retornar estes erros:

    • user not found se o ID do usuário não existir
    • book not found se o ID do livro não existir
    • book not borrowed se o livro já estiver disponível
  • main.go: Reúna tudo criando uma biblioteca, adicionando livros e usuários e, em seguida, processando operações de empréstimo e devolução.

    Leia o número de livros e, depois, para cada livro, leia seu ID, título, autor e ISBN. Em seguida, leia o número de usuários e, para cada usuário, leia seu ID, nome e e-mail. Depois, leia o número de operações, em que cada operação é borrow [userID] [bookID] ou return [userID] [bookID].

    Para cada operação, exiba OK se for bem-sucedida ou Error: [message] se falhar.

As seguintes entradas serão fornecidas:

  • Número de livros, seguido pelo ID, título, autor e ISBN de cada livro (cada um em uma linha separada)
  • Número de usuários, seguido pelo ID, nome e e-mail de cada usuário (cada um em uma linha separada)
  • Número de operações, seguido por cada operação em uma linha separada

Por exemplo, dada a entrada:

2
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Clean Code
Robert Martin
978-0132350884
1
U001
Alice Smith
alice@library.com
4
borrow U001 B001
borrow U001 B001
return U001 B001
borrow U002 B001

Sua saída deve ser:

OK
Error: book not available
OK
Error: user not found

E dada a entrada:

1
B100
Design Patterns
Gang of Four
978-0201633610
2
U001
Bob Jones
bob@email.com
U002
Carol White
carol@email.com
3
borrow U001 B100
borrow U002 B100
return U001 B100

Sua saída deve ser:

OK
Error: book not available
OK

E dada a entrada:

1
B001
Go in Action
William Kennedy
978-1617291784
1
U001
Dave Miller
dave@test.com
2
return U001 B001
borrow U001 B999

Sua saída deve ser:

Error: book not borrowed
Error: book not found

Observe como a Library atua como coordenadora central. Ela valida todas as operações antes de modificar o estado, garantindo que livros e usuários permaneçam sincronizados. O uso de receptores de ponteiro permite que seus métodos modifiquem os dados reais armazenados nos mapas!

Experimente você mesmo

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Ler o número de livros
	var numBooks int
	fmt.Fscanln(reader, &numBooks)

	// TODO: Criar uma nova biblioteca

	// TODO: Ler os detalhes de cada livro (ID, Title, Author, ISBN em linhas separadas)
	// e adicioná-los à biblioteca
	for i := 0; i < numBooks; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		title, _ := reader.ReadString('\n')
		title = strings.TrimSpace(title)
		author, _ := reader.ReadString('\n')
		author = strings.TrimSpace(author)
		isbn, _ := reader.ReadString('\n')
		isbn = strings.TrimSpace(isbn)

		// TODO: Criar livro e adicionar à biblioteca
	}

	// Ler o número de usuários
	var numUsers int
	fmt.Fscanln(reader, &numUsers)

	// TODO: Ler os detalhes de cada usuário (ID, Name, Email em linhas separadas)
	// e adicioná-los à biblioteca
	for i := 0; i < numUsers; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)
		email, _ := reader.ReadString('\n')
		email = strings.TrimSpace(email)

		// TODO: Criar usuário e adicionar à biblioteca
	}

	// Ler o número de operações
	var numOps int
	fmt.Fscanln(reader, &numOps)

	// TODO: Processar cada operação
	// Formato: "borrow [userID] [bookID]" ou "return [userID] [bookID]"
	for i := 0; i < numOps; i++ {
		line, _ := reader.ReadString('\n')
		line = strings.TrimSpace(line)
		parts := strings.Split(line, " ")

		// TODO: Analisar a operação e chamar o método apropriado
		// Imprima "OK" em caso de sucesso ou "Error: [message]" em caso de falha
	}
}

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Go online