JSON 영속성 계층
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 102번째.
챌린지
쉬움Library Management System에 데이터 지속성을 추가해 봅시다! 저장을 위해 라이브러리의 데이터를 JSON 형식으로 변환하고, JSON 문자열에서 다시 불러올 수 있는 JSON 지속성 계층을 구현하게 됩니다. 이는 세션 간에 데이터를 보존해야 하는 실제 애플리케이션에 필수적입니다.
코드를 다섯 개의 파일로 구성합니다.
book.go: 직렬화를 제어하는 JSON 구조체 태그가 포함된Book구조체입니다. 각 필드에는 해당 JSON 태그인id,title,author,isbn,available이 있어야 합니다.NewBookconstructor도 포함하세요.user.go:id,name,email,borrowed_books에 대한 JSON 구조체 태그가 포함된User구조체입니다.NewUserconstructor도 포함하세요.data.go: JSON 직렬화를 위한 transfer object 역할을 하는LibraryData구조체를 생성하세요. 이 구조체에는 두 개의 필드가 있어야 합니다. 하나는 Book 포인터의 슬라이스인Books이고, 다른 하나는 User 포인터의 슬라이스인Users입니다. 각각 적절한 JSON 태그인books와users를 지정하세요.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())
}
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러