대출 시스템
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 100번째.
챌린지
쉬움도서 관리 프로젝트를 위한 대출 시스템을 구축해 봅시다! 도서와 사용자 컬렉션을 관리하는 Library 구조체를 만들고, 적절한 검증 로직을 포함하여 대출 및 반납 작업을 처리하는 메서드를 작성하게 됩니다.
코드는 다음 네 개의 파일로 구성됩니다:
book.go: 이전 레슨에서 만든ID,Title,Author,ISBN,Available필드를 가진Book구조체입니다. 도서를 대출 가능 상태로 초기화하는NewBook생성자를 포함하세요.user.go:ID,Name,Email,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 foundLibrary가 중앙 조정자 역할을 하여 상태를 수정하기 전에 모든 작업을 검증함으로써 도서와 사용자의 동기화를 유지하는 방식에 주목하세요. 포인터 리시버를 사용하면 메서드가 맵에 저장된 실제 데이터를 수정할 수 있습니다!
직접 해보기
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]"를 출력
}
}
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서