JSON永続化レイヤー
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 102/107。
チャレンジ
簡単Library Management System にデータ永続化を追加しましょう!JSON 永続化レイヤーを実装して、保存するために library のデータを JSON 形式に変換し、JSON 文字列から再び読み込めるようにします。これは、セッション間でデータを保持する必要がある実際のアプリケーションに不可欠です。
コードを5つのファイルに整理します。
book.go: シリアル化を制御する JSON 構造体タグを持つBook構造体です。各フィールドには対応する JSON タグ、id、title、author、isbn、availableを設定します。NewBookコンストラクターも含めてください。user.go:id、name、email、borrowed_booksの JSON 構造体タグを持つUser構造体です。NewUserコンストラクターも含めてください。data.go: JSON シリアル化のための転送オブジェクトとして機能するLibraryData構造体を作成します。2つのフィールド、Book ポインターのスライスであるBooksと User ポインターのスライスであるUsersを持たせ、それぞれに適切な JSON タグ(booksとusers)を設定します。library.go: books と users のマップを持つLibrary構造体です。2つの新しいメソッドを追加します。ToJSON():json.MarshalIndentを使用し、2スペースのインデントで library のデータを整形済み JSON 文字列に変換します。マップからすべての books と users を収集してLibraryData構造体に格納し、その後シリアル化します。FromJSON(jsonStr string): JSON 文字列を受け取り、それをLibraryData構造体にアンマーシャルして、読み込んだ books と users を library のマップに格納します。
main.go: library を構築して JSON に変換することで、永続化レイヤーを実演します。books の数を読み取り、次に各 book について ID、title、author、ISBN を読み取ります。続いて users の数を読み取り、各 user について ID、name、email を読み取ります。library にデータを追加したら、
ToJSON()を呼び出して、結果の JSON 文字列を出力します。
次の入力が提供されます。
- books の数、その後に各 book の ID、title、author、ISBN(それぞれ別の行)
- users の数、その後に各 user の ID、name、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: ユーザーのメールを読み取る
// TODO: ユーザーを作成して library に追加する
}
// TODO: library を JSON に変換して出力する
fmt.Println(library.ToJSON())
}
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー自分で練習してみよう: Goオンラインコンパイラ