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éstimo para o nosso projeto de Gerenciamento de Biblioteca! Você criará uma struct Library que gerencia coleções de livros e usuários, com métodos para lidar com operações de checkout e devolução — completo 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). Construa 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 então processando as operações de empréstimo/devolução.

    Leia o número de livros, então 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, onde cada operação é borrow [userID] [bookID] ou return [userID] [bookID].

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

As seguintes entradas serão fornecidas:

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

Por exemplo, dado:

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 dado:

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 dado:

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 o coordenador 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 (pointer receivers) 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.Scanln(&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 o livro e adicionar à biblioteca
	}

	// Ler o número de usuários
	var numUsers int
	fmt.Scanln(&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 o usuário e adicionar à biblioteca
	}

	// Ler o número de operações
	var numOps int
	fmt.Scanln(&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
		// Imprimir "OK" em caso de sucesso ou "Error: [message]" em caso de falha
	}
}

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