Menu
Coddy logo textTech

Система выдачи книг

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy — урок 100 из 107.

challenge icon

Задание

Легко

Давайте создадим систему выдачи книг для нашего проекта управления библиотекой! Вы создадите структуру Library, которая управляет коллекциями книг и пользователей, с методами для обработки операций выдачи и возврата — вместе с соответствующей валидацией.

Вы организуете свой код в четырех файлах:

  • book.go: Ваша структура Book из предыдущего урока с полями ID, Title, Author, ISBN и Available. Включите конструктор NewBook, который инициализирует книги как доступные.
  • user.go: Ваша структура User с полями ID, Name, Email и BorrowedBooks (срез ID книг). Включите конструктор NewUser, который инициализирует пользователей с пустым списком заимствованных книг.
  • library.go: Создайте структуру Library, которая хранит книги и пользователей в картах (ключами являются их ID). Создайте следующие компоненты:
    • Конструктор NewLibrary, который инициализирует пустые карты для книг и пользователей
    • Метод AddBook, который добавляет книгу в библиотеку
    • Метод AddUser, который добавляет пользователя в библиотеку
    • Метод Borrow, который принимает ID пользователя и ID книги, проверяет операцию, помечает книгу как недоступную, добавляет ID книги в список заимствованных книг пользователя и возвращает ошибку, если что-то пошло не так
    • Метод Return, который выполняет процесс, обратный выдаче — помечает книгу как доступную и удаляет ее из списка заимствованных книг пользователя

    Ваш метод Borrow должен возвращать следующие ошибки:

    • "user not found", если ID пользователя не существует
    • "book not found", если ID книги не существует
    • "book not available", если книга уже выдана

    Ваш метод Return должен возвращать следующие ошибки:

    • "user not found", если ID пользователя не существует
    • "book not found", если ID книги не существует
    • "book not borrowed", если книга уже доступна
  • main.go: Объедините все вместе, создав библиотеку, добавив книги и пользователей, а затем обработав операции выдачи/возврата.

    Считайте количество книг, затем для каждой книги считайте ее ID, название, автора и ISBN. Далее считайте количество пользователей, и для каждого пользователя считайте его ID, имя и email. Затем считайте количество операций, где каждая операция представляет собой либо borrow [userID] [bookID], либо return [userID] [bookID].

    Для каждой операции выведите либо OK в случае успеха, либо Error: [message] в случае неудачи.

Будут предоставлены следующие входные данные:

  • Количество книг, затем ID каждой книги, название, автор, ISBN (каждое на отдельной строке)
  • Количество пользователей, затем ID каждого пользователя, имя, email (каждое на отдельной строке)
  • Количество операций, затем каждая операция на отдельной строке

Например, при вводе:

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

Ваш вывод должен быть:

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

И при вводе:

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

Ваш вывод должен быть:

OK
Error: book not available
OK

И при вводе:

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

Ваш вывод должен быть:

Error: book not borrowed
Error: book not found

Обратите внимание, как Library выступает в роли центрального координатора — она проверяет все операции перед изменением состояния, гарантируя синхронизацию данных о книгах и пользователях. Использование получателей-указателей (pointer receivers) позволяет вашим методам изменять фактические данные, хранящиеся в картах!

Попробуйте сами

package main

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

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

	// Считать количество книг
	var numBooks int
	fmt.Scanln(&numBooks)

	// TODO: Создать новую библиотеку

	// TODO: Считать данные каждой книги (ID, Название, Автор, ISBN на отдельных строках)
	// и добавить их в библиотеку
	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: Создать книгу и добавить в библиотеку
	}

	// Считать количество пользователей
	var numUsers int
	fmt.Scanln(&numUsers)

	// TODO: Считать данные каждого пользователя (ID, Имя, Email на отдельных строках)
	// и добавить их в библиотеку
	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: Создать пользователя и добавить в библиотеку
	}

	// Считать количество операций
	var numOps int
	fmt.Scanln(&numOps)

	// TODO: Обработать каждую операцию
	// Формат: "borrow [userID] [bookID]" или "return [userID] [bookID]"
	for i := 0; i < numOps; i++ {
		line, _ := reader.ReadString('\n')
		line = strings.TrimSpace(line)
		parts := strings.Split(line, " ")

		// TODO: Разобрать операцию и вызвать соответствующий метод
		// Вывести "OK" в случае успеха или "Error: [message]" в случае ошибки
	}
}

Все уроки раздела Объектно-ориентированное программирование