Menu
Coddy logo textTech

貸出システム

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 100/107。

challenge icon

チャレンジ

簡単

図書館管理プロジェクトの貸出システムを構築しましょう!本とユーザーのコレクションを管理する Library 構造体を作成し、適切なバリデーションを含む貸出および返却操作を処理するメソッドを実装します。

コードは以下の4つのファイルに分けて構成します:

  • book.go: 前回のレッスンで作成した、IDTitleAuthorISBN、および Available フィールドを持つ Book 構造体です。本を「利用可能」として初期化する NewBook コンストラクタを含めてください。
  • user.go: IDNameEmail、および BorrowedBooks(本のIDのスライス)を持つ User 構造体です。ユーザーを空の貸出リストで初期化する NewUser コンストラクタを含めてください。
  • library.go: 本とユーザーを(それぞれのIDをキーとして)マップに保存する Library 構造体を作成します。以下のコンポーネントを構築してください:
    • 本とユーザーのための空のマップを初期化する NewLibrary コンストラクタ
    • 本を図書館に追加する AddBook メソッド
    • ユーザーを図書館に追加する AddUser メソッド
    • ユーザーIDと本IDを受け取り、操作を検証し、本を「利用不可」に設定し、ユーザーの貸出リストに本IDを追加する Borrow メソッド。問題が発生した場合はエラーを返します。
    • 貸出プロセスを逆に行う Return メソッド。本を「利用可能」に設定し、ユーザーの貸出リストから削除します。

    Borrow メソッドは以下のエラーを返す必要があります:

    • ユーザーIDが存在しない場合は "user not found"
    • 本IDが存在しない場合は "book not found"
    • 本がすでに貸し出されている場合は "book not available"

    Return メソッドは以下のエラーを返す必要があります:

    • ユーザーIDが存在しない場合は "user not found"
    • 本IDが存在しない場合は "book not found"
    • 本がすでに利用可能な状態(貸し出されていない)の場合は "book not borrowed"
  • main.go: 図書館を作成し、本とユーザーを追加し、貸出/返却操作を処理することで、すべてをまとめます。

    本の数を読み取り、次に各本のID、タイトル、著者、ISBNを読み取ります。次にユーザーの数を読み取り、各ユーザーのID、名前、メールアドレスを読み取ります。その後、操作の数を読み取ります。各操作は "borrow [userID] [bookID]" または "return [userID] [bookID]" の形式です。

    各操作について、成功した場合は "OK" を、失敗した場合は "Error: [message]" を出力してください。

以下の入力が提供されます:

  • 本の数、続いて各本のID、タイトル、著者、ISBN(それぞれ別々の行)
  • ユーザーの数、続いて各ユーザーのID、名前、メールアドレス(それぞれ別々の行)
  • 操作の数、続いて各操作(別々の行)

例えば、以下のように入力された場合:

2
B001
The Go Programming Language
Alan Donovan
978-0134190440
B002
Clean Code
Robert Martin
978-0132350884
1
U001
Alice Smith
alice@library.com
4
borrow U001 B001
borrow U001 B001
return U001 B001
borrow U002 B001

出力は以下のようになります:

OK
Error: book not available
OK
Error: user not found

また、以下のように入力された場合:

1
B100
Design Patterns
Gang of Four
978-0201633610
2
U001
Bob Jones
bob@email.com
U002
Carol White
carol@email.com
3
borrow U001 B100
borrow U002 B100
return U001 B100

出力は以下のようになります:

OK
Error: book not available
OK

また、以下のように入力された場合:

1
B001
Go in Action
William Kennedy
978-1617291784
1
U001
Dave Miller
dave@test.com
2
return U001 B001
borrow U001 B999

出力は以下のようになります:

Error: book not borrowed
Error: book not found

Libraryが中央のコーディネーターとして機能し、状態を変更する前にすべての操作を検証して、本とユーザーの同期を保つ仕組みに注目してください。ポインタレシーバを使用することで、メソッドがマップに保存されている実際のデータを変更できるようになります!

自分で試してみよう

package main

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

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

	// 本の数を読み込む
	var numBooks int
	fmt.Scanln(&numBooks)

	// TODO: 新しいライブラリを作成する

	// TODO: 各本の詳細(ID、Title、Author、ISBN を別々の行で)を読み込む
	// そしてそれらをライブラリに追加する
	for i := 0; i < numBooks; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		title, _ := reader.ReadString('\n')
		title = strings.TrimSpace(title)
		author, _ := reader.ReadString('\n')
		author = strings.TrimSpace(author)
		isbn, _ := reader.ReadString('\n')
		isbn = strings.TrimSpace(isbn)

		// TODO: 本を作成してライブラリに追加する
	}

	// ユーザーの数を読み込む
	var numUsers int
	fmt.Scanln(&numUsers)

	// TODO: 各ユーザーの詳細(ID、Name、Email を別々の行で)を読み込む
	// そしてそれらをライブラリに追加する
	for i := 0; i < numUsers; i++ {
		id, _ := reader.ReadString('\n')
		id = strings.TrimSpace(id)
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)
		email, _ := reader.ReadString('\n')
		email = strings.TrimSpace(email)

		// TODO: ユーザーを作成してライブラリに追加する
	}

	// 操作の数を読み込む
	var numOps int
	fmt.Scanln(&numOps)

	// TODO: 各操作を処理する
	// 形式: "borrow [userID] [bookID]" または "return [userID] [bookID]"
	for i := 0; i < numOps; i++ {
		line, _ := reader.ReadString('\n')
		line = strings.TrimSpace(line)
		parts := strings.Split(line, " ")

		// TODO: 操作を解析し、適切なメソッドを呼び出す
		// 成功時には "OK" を、失敗時には "Error: [message]" を出力する
	}
}

オブジェクト指向プログラミングのすべてのレッスン