"======================================================================
Class: Book
======================================================================"
Object subclass: Book [
| title author isBorrowed |
"クラスメソッド: インスタンス生成用"
Book class >> title: aTitle author: anAuthor [
^self new setTitle: aTitle author: anAuthor
]
setTitle: aTitle author: anAuthor [
title := aTitle.
author := anAuthor.
isBorrowed := false.
]
"ゲッター / セッター"
title [ ^title ]
author [ ^author ]
isBorrowed [ ^isBorrowed ]
isBorrowed: aBoolean [ isBorrowed := aBoolean ]
"文字列表現"
asString [
^title , ' (by ' , author , ')' , (isBorrowed ifTrue: [ ' [貸出中]' ] ifFalse: [ ' [貸出可能]' ])
]
]
"======================================================================
Class: User
======================================================================"
Object subclass: User [
| name borrowedBooks maxBooks |
"クラスメソッド: インスタンス生成用"
User class >> name: aName maxBooks: aLimit [
^self new setName: aName maxBooks: aLimit
]
setName: aName maxBooks: aLimit [
name := aName.
maxBooks := aLimit.
borrowedBooks := OrderedCollection new.
]
"ゲッター"
name [ ^name ]
borrowedBooks [ ^borrowedBooks ]
"ビジネスロジック: まだ借りられるか判定"
canBorrowMore [
^borrowedBooks size < maxBooks
]
borrowBook: aBook [
borrowedBooks add: aBook.
]
returnBook: aBook [
borrowedBooks remove: aBook ifAbsent: [].
]
]
"======================================================================
Class: Library
======================================================================"
Object subclass: Library [
| books users |
"クラスメソッド: 初期化を伴うインスタンス作成"
Library class >> new [
^super new initialize
]
initialize [
books := OrderedCollection new.
users := OrderedCollection new.
]
"管理リストへの追加"
addBook: aBook [ books add: aBook ]
addUser: aUser [ users add: aUser ]
"貸出メソッド"
checkoutBook: aBook forUser: aUser [
"バリデーション"
(books includes: aBook) ifFalse: [
'【エラー】この本は図書館に登録されていません。' printNl. ^false
].
(users includes: aUser) ifFalse: [
'【エラー】この利用者は登録されていません。' printNl. ^false
].
aBook isBorrowed ifTrue: [
('【エラー】「' , aBook title , '」はすでに貸出中です。') printNl. ^false
].
aUser canBorrowMore ifFalse: [
('【エラー】' , aUser name , ' 様は貸出上限(制限数に達しています)を超えています。') printNl. ^false
].
"貸出の実行(状態変更)"
aBook isBorrowed: true.
aUser borrowBook: aBook.
(aUser name , ' 様が「' , aBook title , '」を借りました。') printNl.
^true
]
"返却メソッド"
returnBook: aBook fromUser: aUser [
(aUser borrowedBooks includes: aBook) ifFalse: [
('【エラー】' , aUser name , ' 様はこの本を借りていません。') printNl. ^false
].
"返却の実行(状態変更)"
aBook isBorrowed: false.
aUser returnBook: aBook.
(aUser name , ' 様が「' , aBook title , '」を返却しました。') printNl.
^true
]
"現在のステータス表示"
printStatus [
'---------------------------------------' printNl.
'【図書館ステータス】' printNl.
'■ 蔵書一覧:' printNl.
books do: [ :each | (' - ' , each asString) printNl ].
'■ 利用者一覧:' printNl.
users do: [ :each |
(' - ' , each name , ' (貸出中: ' , each borrowedBooks size printString , '冊)') printNl.
].
'---------------------------------------' printNl.
]
]
"======================================================================
テストスクリプトの実行(メインルーチン)
======================================================================"
| myLibrary book1 book2 book3 student prof |
"1. 図書館の作成"
myLibrary := Library new.
"2. 本の登録"
book1 := Book title: 'Smalltalk-80 Blue Book' author: 'Adele Goldberg'.
book2 := Book title: 'Design Patterns' author: 'GoF'.
book3 := Book title: 'Squeak by Example' author: 'Stephane Ducasse'.
myLibrary addBook: book1; addBook: book2; addBook: book3.
"3. ユーザーの登録(学生は上限2冊、教授は上限5冊)"
student := User name: '山田太郎(学生)' maxBooks: 2.
prof := User name: 'スミス教授' maxBooks: 5.
myLibrary addUser: student; addUser: prof.
"--- 初期状態の出力 ---"
myLibrary printStatus.
"--- 貸出シミュレーション ---"
'>>> シナリオ1: 山田さんが2冊借りる' printNl.
myLibrary checkoutBook: book1 forUser: student.
myLibrary checkoutBook: book2 forUser: student.
'>>> シナリオ2: 山田さんが3冊目を借りようとする(上限エラーになるはず)' printNl.
myLibrary checkoutBook: book3 forUser: student.
'>>> シナリオ3: スミス教授が山田さんの借りている本を借りようとする(貸出中エラーになるはず)' printNl.
myLibrary checkoutBook: book1 forUser: prof.
'>>> シナリオ4: スミス教授が空いている本を借りる(成功するはず)' printNl.
myLibrary checkoutBook: book3 forUser: prof.
myLibrary printStatus.
'>>> シナリオ5: 山田さんが1冊返却し、再度別の人に貸し出せるようにする' printNl.
myLibrary returnBook: book1 fromUser: student.
myLibrary printStatus.