"============================================================"
" 大学図書館貸出システム"
" Ideone / GNU Smalltalk用"
"============================================================"
"------------------------------------------------------------"
" Bookクラス"
"------------------------------------------------------------"
Object subclass: #Book
instanceVariableNames: 'isbn title author available'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Book methodsFor: 'initialization'!
initializeISBN: anISBN title: aTitle author: anAuthor
isbn := anISBN.
title := aTitle.
author := anAuthor.
available := true.
^self
!
! !
!Book methodsFor: 'accessing'!
isbn
^isbn
!
title
^title
!
author
^author
!
isAvailable
^available
!
statusText
available ifTrue: [^'貸出可能'].
^'貸出中'
!
! !
!Book methodsFor: 'loan operations'!
borrow
available ifFalse: [
self error: 'この図書はすでに貸出中です'
].
available := false.
^self
!
returnBook
available ifTrue: [
self error: 'この図書は貸出されていません'
].
available := true.
^self
!
! !
!Book methodsFor: 'printing'!
printOn: aStream
aStream nextPutAll: title.
aStream nextPutAll: ' / '.
aStream nextPutAll: author.
aStream nextPutAll: ' [ISBN: '.
aStream nextPutAll: isbn.
aStream nextPutAll: '] '.
aStream nextPutAll: self statusText
!
! !
"------------------------------------------------------------"
" Memberクラス"
"------------------------------------------------------------"
Object subclass: #Member
instanceVariableNames: 'memberId memberName memberType'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Member methodsFor: 'initialization'!
initializeId: anId name: aName type: aType
memberId := anId.
memberName := aName.
memberType := aType.
^self
!
! !
!Member methodsFor: 'accessing'!
memberId
^memberId
!
name
^memberName
!
memberType
^memberType
!
typeName
memberType = #student ifTrue: [^'学生'].
memberType = #teacher ifTrue: [^'教職員'].
^'その他'
!
loanLimit
memberType = #student ifTrue: [^3].
memberType = #teacher ifTrue: [^10].
^2
!
loanPeriod
memberType = #teacher ifTrue: [^30].
^14
!
! !
!Member methodsFor: 'printing'!
printOn: aStream
aStream nextPutAll: memberName.
aStream nextPutAll: ' [利用者番号: '.
aStream nextPutAll: memberId.
aStream nextPutAll: ', 区分: '.
aStream nextPutAll: self typeName.
aStream nextPutAll: ', 貸出上限: '.
aStream nextPutAll: self loanLimit printString.
aStream nextPutAll: '冊]'
!
! !
"------------------------------------------------------------"
" Loanクラス"
" 日付は整数で表現する"
"------------------------------------------------------------"
Object subclass: #Loan
instanceVariableNames: 'loanBook loanMember loanDay dueDay returnedDay'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Loan methodsFor: 'initialization'!
initializeBook: aBook member: aMember day: aDay
loanBook := aBook.
loanMember := aMember.
loanDay := aDay.
dueDay := aDay + aMember loanPeriod.
returnedDay := nil.
^self
!
! !
!Loan methodsFor: 'accessing'!
book
^loanBook
!
member
^loanMember
!
loanDay
^loanDay
!
dueDay
^dueDay
!
returnedDay
^returnedDay
!
isActive
^returnedDay isNil
!
! !
!Loan methodsFor: 'testing'!
isOverdueOn: currentDay
self isActive ifFalse: [^false].
^currentDay > dueDay
!
overdueDaysOn: currentDay
(self isOverdueOn: currentDay) ifFalse: [^0].
^currentDay - dueDay
!
! !
!Loan methodsFor: 'returning'!
returnOn: aDay
self isActive ifFalse: [
self error: 'この貸出記録はすでに返却済みです'
].
returnedDay := aDay.
loanBook returnBook.
^self
!
! !
!Loan methodsFor: 'printing'!
printOn: aStream
aStream nextPutAll: loanMember name.
aStream nextPutAll: ' -> '.
aStream nextPutAll: loanBook title.
aStream nextPutAll: ' / 貸出日: '.
aStream nextPutAll: loanDay printString.
aStream nextPutAll: ' / 返却期限: '.
aStream nextPutAll: dueDay printString.
self isActive
ifTrue: [
aStream nextPutAll: ' / 貸出中'
]
ifFalse: [
aStream nextPutAll: ' / 返却日: '.
aStream nextPutAll: returnedDay printString.
aStream nextPutAll: ' / 返却済み'
]
!
! !
"------------------------------------------------------------"
" Libraryクラス"
"------------------------------------------------------------"
Object subclass: #Library
instanceVariableNames: 'libraryName books members loans'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Library methodsFor: 'initialization'!
initializeName: aName
libraryName := aName.
books := OrderedCollection new.
members := OrderedCollection new.
loans := OrderedCollection new.
^self
!
! !
!Library methodsFor: 'accessing'!
name
^libraryName
!
books
^books
!
members
^members
!
loans
^loans
!
! !
!Library methodsFor: 'registration'!
addBook: aBook
(self findBookByISBN: aBook isbn) notNil ifTrue: [
self error: '同じISBNの図書が登録されています'
].
books add: aBook.
^aBook
!
registerMember: aMember
(self findMemberById: aMember memberId) notNil ifTrue: [
self error: '同じ利用者番号が登録されています'
].
members add: aMember.
^aMember
!
! !
!Library methodsFor: 'searching'!
findBookByISBN: anISBN
books do: [:each |
each isbn = anISBN ifTrue: [^each]
].
^nil
!
findMemberById: anId
members do: [:each |
each memberId = anId ifTrue: [^each]
].
^nil
!
activeLoansFor: aMember
| result |
result := OrderedCollection new.
loans do: [:each |
each member == aMember ifTrue: [
each isActive ifTrue: [
result add: each
]
]
].
^result
!
activeLoanForBook: aBook
loans do: [:each |
each book == aBook ifTrue: [
each isActive ifTrue: [^each]
]
].
^nil
!
! !
!Library methodsFor: 'loan operations'!
lendISBN: anISBN toMember: anId onDay: aDay
| targetBook targetMember currentLoans newLoan |
targetBook := self findBookByISBN: anISBN.
targetBook isNil ifTrue: [
self error: '指定された図書が見つかりません'
].
targetMember := self findMemberById: anId.
targetMember isNil ifTrue: [
self error: '指定された利用者が見つかりません'
].
targetBook isAvailable ifFalse: [
self error: '指定された図書はすでに貸出中です'
].
currentLoans := self activeLoansFor: targetMember.
currentLoans size >= targetMember loanLimit ifTrue: [
self error: '貸出可能冊数を超えています'
].
targetBook borrow.
newLoan := Loan new
initializeBook: targetBook
member: targetMember
day: aDay.
loans add: newLoan.
^newLoan
!
returnISBN: anISBN onDay: aDay
| targetBook targetLoan |
targetBook := self findBookByISBN: anISBN.
targetBook isNil ifTrue: [
self error: '指定された図書が見つかりません'
].
targetLoan := self activeLoanForBook: targetBook.
targetLoan isNil ifTrue: [
self error: '指定された図書は現在貸出されていません'
].
targetLoan returnOn: aDay.
^targetLoan
!
! !
!Library methodsFor: 'reporting'!
showBooks
'' printNl.
'===== 図書一覧 =====' printNl.
books isEmpty ifTrue: [
'登録されている図書はありません' printNl
].
books do: [:each |
each printString printNl
]
!
showMembers
'' printNl.
'===== 利用者一覧 =====' printNl.
members isEmpty ifTrue: [
'登録されている利用者はいません' printNl
].
members do: [:each |
each printString printNl
]
!
showActiveLoans
| count |
count := 0.
'' printNl.
'===== 現在の貸出一覧 =====' printNl.
loans do: [:each |
each isActive ifTrue: [
each printString printNl.
count := count + 1
]
].
count = 0 ifTrue: [
'現在貸出中の図書はありません' printNl
]
!
showOverdueLoansOn: currentDay
| count |
count := 0.
'' printNl.
'===== 延滞一覧 =====' printNl.
('確認日: ' , currentDay printString , '日目') printNl.
loans do: [:each |
(each isOverdueOn: currentDay) ifTrue: [
each printString print.
' / 延滞日数: ' print.
(each overdueDaysOn: currentDay) print.
'日' printNl.
count := count + 1
]
].
count = 0 ifTrue: [
'現在延滞中の貸出はありません' printNl
]
!
showLoanHistory
'' printNl.
'===== 全貸出履歴 =====' printNl.
loans isEmpty ifTrue: [
'貸出履歴はありません' printNl
].
loans do: [:each |
each printString printNl
]
!
! !
"============================================================"
" メインプログラム"
"============================================================"
Eval [
| library book1 book2 book3 student teacher loan1 loan2 returnedLoan |
library := Library new
initializeName: '○○大学図書館'.
book1 := Book new
initializeISBN: '978-4-00-000001-1'
title: 'Smalltalk入門'
author: '山田太郎'.
book2 := Book new
initializeISBN: '978-4-00-000002-8'
title: 'オブジェクト指向設計'
author: '佐藤花子'.
book3 := Book new
initializeISBN: '978-4-00-000003-5'
title: 'データベース基礎'
author: '鈴木一郎'.
student := Member new
initializeId: 'S2023001'
name: '田中学生'
type: #student.
teacher := Member new
initializeId: 'T1001'
name: '佐々木教授'
type: #teacher.
library addBook: book1.
library addBook: book2.
library addBook: book3.
library registerMember: student.
library registerMember: teacher.
'========================================' printNl.
'大学図書館貸出システムを開始します' printNl.
('図書館名: ' , library name) printNl.
'========================================' printNl.
library showBooks.
library showMembers.
loan1 := library
lendISBN: '978-4-00-000001-1'
toMember: 'S2023001'
onDay: 100.
'' printNl.
'===== 貸出処理結果1 =====' printNl.
loan1 printString printNl.
loan2 := library
lendISBN: '978-4-00-000002-8'
toMember: 'T1001'
onDay: 105.
'' printNl.
'===== 貸出処理結果2 =====' printNl.
loan2 printString printNl.
library showActiveLoans.
library showBooks.
library showOverdueLoansOn: 120.
returnedLoan := library
returnISBN: '978-4-00-000001-1'
onDay: 121.
'' printNl.
'===== 返却処理結果 =====' printNl.
returnedLoan printString printNl.
library showActiveLoans.
library showBooks.
library showOverdueLoansOn: 140.
library showLoanHistory.
'' printNl.
'========================================' printNl.
'大学図書館貸出システムを終了します' printNl.
'========================================' printNl
]