Menu
Coddy logo textTech

JSON 영속성 계층

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 102번째.

challenge icon

챌린지

쉬움

Library Management System에 데이터 지속성을 추가해 봅시다! 저장을 위해 라이브러리의 데이터를 JSON 형식으로 변환하고, JSON 문자열에서 다시 불러올 수 있는 JSON 지속성 계층을 구현하게 됩니다. 이는 세션 간에 데이터를 보존해야 하는 실제 애플리케이션에 필수적입니다.

코드를 다섯 개의 파일로 구성합니다.

  • book.go: 직렬화를 제어하는 JSON 구조체 태그가 포함된 Book 구조체입니다. 각 필드에는 해당 JSON 태그인 id, title, author, isbn, available이 있어야 합니다. NewBook constructor도 포함하세요.
  • user.go: id, name, email, borrowed_books에 대한 JSON 구조체 태그가 포함된 User 구조체입니다. NewUser constructor도 포함하세요.
  • data.go: JSON 직렬화를 위한 transfer object 역할을 하는 LibraryData 구조체를 생성하세요. 이 구조체에는 두 개의 필드가 있어야 합니다. 하나는 Book 포인터의 슬라이스인 Books이고, 다른 하나는 User 포인터의 슬라이스인 Users입니다. 각각 적절한 JSON 태그인 booksusers를 지정하세요.
  • library.go: books와 users를 위한 맵이 포함된 Library 구조체입니다. 다음 두 개의 새 메서드를 추가하세요.
    • ToJSON(): json.MarshalIndent를 사용하고 두 칸 들여쓰기를 적용하여 라이브러리의 데이터를 형식이 지정된 JSON 문자열로 변환합니다. 맵에서 모든 책과 사용자를 수집하여 LibraryData 구조체에 넣은 다음 직렬화해야 합니다.
    • FromJSON(jsonStr string): JSON 문자열을 받아 LibraryData 구조체로 역직렬화하고, 불러온 책과 사용자로 라이브러리의 맵을 채웁니다.
  • main.go: 라이브러리를 구성하고 JSON으로 변환하여 지속성 계층을 시연합니다.

    책의 수를 읽은 다음, 각 책에 대해 ID, 제목, author, ISBN을 읽으세요. 다음으로 사용자의 수를 읽고, 각 사용자에 대해 ID, 이름, email을 읽으세요. 라이브러리를 채운 후 ToJSON()을 호출하고 결과 JSON 문자열을 출력하세요.

다음 입력이 제공됩니다.

  • 책의 수, 이어서 각 책의 ID, 제목, author, 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의 배열 기반 형식 사이를 연결합니다. 이 transfer object 패턴은 복잡한 데이터 구조를 직렬화할 때 흔히 사용됩니다!

직접 해보기

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: 사용자 이메일 읽기
		// TODO: 사용자를 생성하고 library에 추가
	}

	// TODO: library를 JSON으로 변환하고 출력
	fmt.Println(library.ToJSON())
}

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러