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 с отображениями для books и users. Добавьте два новых метода:
    • ToJSON(): преобразует данные библиотеки в отформатированную строку JSON с использованием json.MarshalIndent и отступа в два пробела. Метод должен собрать все books и users из отображений в структуру LibraryData, а затем сериализовать её.
    • FromJSON(jsonStr string): принимает строку JSON, десериализует её в структуру LibraryData и заполняет отображения библиотеки загруженными books и users.
  • main.go: продемонстрируйте работу слоя сохранения данных, создав библиотеку и преобразовав её в JSON.

    Прочитайте количество books, затем для каждой книги прочитайте её ID, название, author и ISBN. Затем прочитайте количество users, а для каждого пользователя — его ID, имя и email. После заполнения библиотеки вызовите ToJSON() и выведите получившуюся строку JSON.

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

  • Количество books, затем ID, название, author и ISBN каждой книги (каждое значение в отдельной строке)
  • Количество users, затем 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": []
}

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

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

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

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: Прочитать имя пользователя
		// TODO: Прочитать email пользователя
		// TODO: Создать пользователя и добавить в библиотеку
	}

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

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

Потренируйтесь самостоятельно: Онлайн-компилятор Go