Menu
Coddy logo textTech

Слой хранения JSON

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

challenge icon

Задание

Легко

Давайте добавим сохранение данных в нашу систему управления библиотекой! Вы реализуете слой персистентности JSON, который сможет преобразовывать данные вашей библиотеки в формат JSON для сохранения и загружать их обратно из строк JSON. Это необходимо для любого реального приложения, которому нужно сохранять данные между сеансами.

Вы распределите свой код по пяти файлам:

  • book.go: Ваша структура Book с тегами JSON для управления сериализацией. Каждое поле должно иметь соответствующий тег JSON: id, title, author, isbn и available. Включите ваш конструктор NewBook.
  • user.go: Ваша структура User с тегами JSON для id, name, email и borrowed_books. Включите ваш конструктор NewUser.
  • data.go: Создайте структуру LibraryData, которая будет выступать в качестве объекта передачи данных для сериализации JSON. Она должна иметь два поля: Books (срез указателей на Book) и Users (срез указателей на User), каждое с соответствующими тегами JSON (books и users).
  • library.go: Ваша структура Library с картами (maps) для книг и пользователей. Добавьте два новых метода:
    • ToJSON() — преобразует данные библиотеки в отформатированную строку JSON, используя json.MarshalIndent с отступом в два пробела. Он должен собрать все книги и пользователей из карт в структуру LibraryData, а затем сериализовать ее.
    • FromJSON(jsonStr string) — принимает строку JSON, десериализует ее в структуру LibraryData и заполняет карты библиотеки загруженными книгами и пользователями.
  • main.go: Продемонстрируйте слой персистентности, создав библиотеку и преобразовав ее в JSON.

    Считайте количество книг, затем для каждой книги считайте ее ID, название, автора и ISBN. Далее считайте количество пользователей, и для каждого пользователя считайте его ID, имя и email. После заполнения библиотеки вызовите ToJSON() и выведите полученную строку JSON.

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

  • Количество книг, затем 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

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

{
  "books": [
    {
      "id": "B001",
      "title": "The Go Programming Language",
      "author": "Alan Donovan",
      "isbn": "978-0134190440",
      "available": true
    },
    {
      "id": "B002",
      "title": "Clean Code",
      "author": "Robert Martin",
      "isbn": "978-0132350884",
      "available": true
    }
  ],
  "users": [
    {
      "id": "U001",
      "name": "Alice Smith",
      "email": "alice@library.com",
      "borrowed_books": []
    }
  ]
}

И при вводе:

1
B100
Design Patterns
Gang of Four
978-0201633610
0

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

{
  "books": [
    {
      "id": "B100",
      "title": "Design Patterns",
      "author": "Gang of Four",
      "isbn": "978-0201633610",
      "available": true
    }
  ],
  "users": []
}

Важно: При итерации по картам для создания срезов добавляйте книги в следующем порядке: B001, B002 и т. д. (отсортированные по ID в алфавитном порядке), и пользователей аналогично. Это обеспечит согласованный вывод JSON. Вы можете использовать sort.Strings для ключей карты перед итерацией.

Структура LibraryData устраняет разрыв между вашим хранилищем на основе карт и форматом JSON на основе массивов. Этот паттерн объекта передачи данных (DTO) часто встречается при сериализации сложных структур данных!

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

package main

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

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

	// Создать новую библиотеку
	library := NewLibrary()

	// Прочитать количество книг
	numBooksStr, _ := reader.ReadString('\n')
	numBooks, _ := strconv.Atoi(strings.TrimSpace(numBooksStr))

	// TODO: Прочитать данные каждой книги (ID, title, author, ISBN)
	// и добавить их в библиотеку
	for i := 0; i < numBooks; i++ {
		// TODO: Прочитать ID книги
		// TODO: Прочитать title книги
		// TODO: Прочитать author книги
		// TODO: Прочитать ISBN книги
		// TODO: Создать книгу и добавить в библиотеку
	}

	// Прочитать количество пользователей
	numUsersStr, _ := reader.ReadString('\n')
	numUsers, _ := strconv.Atoi(strings.TrimSpace(numUsersStr))

	// TODO: Прочитать данные каждого пользователя (ID, name, email)
	// и добавить их в библиотеку
	for i := 0; i < numUsers; i++ {
		// TODO: Прочитать ID пользователя
		// TODO: Прочитать name пользователя
		// TODO: Прочитать email пользователя
		// TODO: Создать пользователя и добавить в библиотеку
	}

	// TODO: Преобразовать библиотеку в JSON и вывести её
	fmt.Println(library.ToJSON())
}

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