"============================================================"
" 大学図書館貸出システム"
" Ideone / GNU Smalltalk向け"
"============================================================"
"------------------------------------------------------------"
" Book:図書"
"------------------------------------------------------------"
Object subclass: #Book
instanceVariableNames: 'isbn title author available'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Book class methodsFor: 'instance creation'!
isbn: anISBN title: aTitle author: anAuthor
^self new
initializeISBN: anISBN
title: aTitle
author: anAuthor
!
!
!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
!
!
!Book methodsFor: 'loan operations'!
borrow
available
ifFalse: [self error: 'この図書はすでに貸出中です'].
available := false
!
returnBook
available
ifTrue: [self error: 'この図書は貸出されていません'].
available := true
!
!
!Book methodsFor: 'printing'!
printOn: aStream
aStream
nextPutAll: title;
nextPutAll: ' / ';
nextPutAll: author;
nextPutAll: ' [ISBN: ';
nextPutAll: isbn;
nextPutAll: ']'.
available
ifTrue: [aStream nextPutAll: ' 貸出可能']
ifFalse: [aStream nextPutAll: ' 貸出中']
!
!
"------------------------------------------------------------"
" Member:図書館利用者"
"------------------------------------------------------------"
Object subclass: #Member
instanceVariableNames: 'memberId name memberType'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Member class methodsFor: 'instance creation'!
id: anId name: aName type: aType
^self new
initializeId: anId
name: aName
type: aType
!
!
!Member methodsFor: 'initialization'!
initializeId: anId name: aName type: aType
memberId := anId.
name := aName.
memberType := aType.
^self
!
!
!Member methodsFor: 'accessing'!
memberId
^memberId
!
name
^name
!
memberType
^memberType
!
loanLimit
memberType = #student
ifTrue: [^3].
memberType = #teacher
ifTrue: [^10].
^2
!
loanPeriod
memberType = #teacher
ifTrue: [^30].
^14
!
typeName
memberType = #student
ifTrue: [^'学生'].
memberType = #teacher
ifTrue: [^'教職員'].
^'その他'
!
!
!Member methodsFor: 'printing'!
printOn: aStream
aStream
nextPutAll: name;
nextPutAll: ' [利用者番号: ';
nextPutAll: memberId;
nextPutAll: ', 区分: ';
nextPutAll: self typeName;
nextPutAll: ']'
!
!
"------------------------------------------------------------"
" Loan:貸出記録"
" 日付は、例を簡単にするため整数の日数で表現する"
"------------------------------------------------------------"
Object subclass: #Loan
instanceVariableNames: 'book member loanDay dueDay returnedDay'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Loan class methodsFor: 'instance creation'!
book: aBook member: aMember loanDay: aLoanDay
^self new
initializeBook: aBook
member: aMember
loanDay: aLoanDay
!
!
!Loan methodsFor: 'initialization'!
initializeBook: aBook member: aMember loanDay: aLoanDay
book := aBook.
member := aMember.
loanDay := aLoanDay.
dueDay := aLoanDay + member loanPeriod.
returnedDay := nil.
^self
!
!
!Loan methodsFor: 'accessing'!
book
^book
!
member
^member
!
loanDay
^loanDay
!
dueDay
^dueDay
!
returnedDay
^returnedDay
!
isActive
^returnedDay isNil
!
isOverdueOn: currentDay
^self isActive and: [currentDay > dueDay]
!
!
!Loan methodsFor: 'returning'!
returnOn: aDay
self isActive
ifFalse: [self error: 'この貸出記録はすでに返却済みです'].
returnedDay := aDay.
book returnBook
!
!
!Loan methodsFor: 'printing'!
printOn: aStream
aStream
nextPutAll: member name;
nextPutAll: ' -> ';
nextPutAll: book title;
nextPutAll: ' / 貸出日: ';
print: loanDay;
nextPutAll: ' / 返却期限: ';
print: dueDay.
self isActive
ifTrue: [aStream nextPutAll: ' / 貸出中']
ifFalse: [
aStream
nextPutAll: ' / 返却日: ';
print: returnedDay
]
!
!
"------------------------------------------------------------"
" Library:大学図書館"
"------------------------------------------------------------"
Object subclass: #Library
instanceVariableNames: 'name books members loans'
classVariableNames: ''
poolDictionaries: ''
category: 'UniversityLibrary'!
!Library class methodsFor: 'instance creation'!
named: aName
^self new initializeName: aName
!
!
!Library methodsFor: 'initialization'!
initializeName: aName
name := aName.
books := OrderedCollection new.
members := OrderedCollection new.
loans := OrderedCollection new.
^self
!
!
!Library methodsFor: 'registration'!
addBook: aBook
(self findBookByISBN: aBook isbn) notNil
ifTrue: [self error: '同じISBNの図書が登録されています'].
books add: aBook
!
registerMember: aMember
(self findMemberById: aMember memberId) notNil
ifTrue: [self error: '同じ利用者番号が登録されています'].
members add: 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
!
findBooksByTitle: aKeyword
| result |
result := OrderedCollection new.
books do: [:each |
(each title includesSubString: aKeyword)
ifTrue: [result add: each]
].
^result
!
activeLoansFor: aMember
| result |
result := OrderedCollection new.
loans do: [:each |
(each member == aMember and: [each isActive])
ifTrue: [result add: each]
].
^result
!
activeLoanForBook: aBook
loans do: [:each |
(each book == aBook and: [each isActive])
ifTrue: [^each]
].
^nil
!
!
!Library methodsFor: 'loan operations'!
lendISBN: anISBN toMember: anId onDay: aDay
| book member activeLoans loan |
book := self findBookByISBN: anISBN.
book isNil
ifTrue: [self error: '指定された図書が見つかりません'].
member := self findMemberById: anId.
member isNil
ifTrue: [self error: '指定された利用者が見つかりません'].
book isAvailable
ifFalse: [self error: '指定された図書は貸出中です'].
activeLoans := self activeLoansFor: member.
activeLoans size >= member loanLimit
ifTrue: [self error: '貸出可能冊数を超えています'].
book borrow.
loan := Loan
book: book
member: member
loanDay: aDay.
loans add: loan.
^loan
!
returnISBN: anISBN onDay: aDay
| book loan |
book := self findBookByISBN: anISBN.
book isNil
ifTrue: [self error: '指定された図書が見つかりません'].
loan := self activeLoanForBook: book.
loan isNil
ifTrue: [self error: 'この図書の有効な貸出記録がありません'].
loan returnOn: aDay.
^loan
!
!
!Library methodsFor: 'reporting'!
showBooks
Transcript
cr;
show: '===== 図書一覧 =====';
cr.
books do: [:each |
Transcript
show: each printString;
cr
]
!
showMembers
Transcript
cr;
show: '===== 利用者一覧 =====';
cr.
members do: [:each |
Transcript
show: each printString;
cr
]
!
showActiveLoans
Transcript
cr;
show: '===== 現在の貸出一覧 =====';
cr.
loans do: [:each |
each isActive
ifTrue: [
Transcript
show: each printString;
cr
]
]
!
showOverdueLoansOn: currentDay
Transcript
cr;
show: '===== 延滞一覧 =====';
cr.
loans do: [:each |
(each isOverdueOn: currentDay)
ifTrue: [
Transcript
show: each printString;
show: ' / 延滞日数: ';
show: (currentDay - each dueDay) printString;
cr
]
]
!
!
"============================================================"
" 実行例"
"============================================================"
Eval [
| library book1 book2 book3 student teacher loan1 loan2 |
library := Library named: '○○大学図書館'.
"図書を作成"
book1 := Book
isbn: '978-4-00-000001-1'
title: 'Smalltalk入門'
author: '山田太郎'.
book2 := Book
isbn: '978-4-00-000002-8'
title: 'オブジェクト指向設計'
author: '佐藤花子'.
book3 := Book
isbn: '978-4-00-000003-5'
title: 'データベース基礎'
author: '鈴木一郎'.
"利用者を作成"
student := Member
id: 'S2023001'
name: '田中学生'
type: #student.
teacher := Member
id: 'T1001'
name: '佐々木教授'
type: #teacher.
"図書を登録"
library addBook: book1.
library addBook: book2.
library addBook: book3.
"利用者を登録"
library registerMember: student.
library registerMember: teacher.
Transcript
show: '大学図書館貸出システムを開始します';
cr.
library showBooks.
library showMembers.
"100日目に学生が借りる"
loan1 := library
lendISBN: '978-4-00-000001-1'
toMember: 'S2023001'
onDay: 100.
Transcript
cr;
show: '貸出処理: ';
show: loan1 printString;
cr.
"105日目に教職員が借りる"
loan2 := library
lendISBN: '978-4-00-000002-8'
toMember: 'T1001'
onDay: 105.
Transcript
show: '貸出処理: ';
show: loan2 printString;
cr.
library showActiveLoans.
library showBooks.
"120日目時点の延滞を確認"
library showOverdueLoansOn: 120.
"学生が121日目に返却"
library
returnISBN: '978-4-00-000001-1'
onDay: 121.
Transcript
cr;
show: 'Smalltalk入門を返却しました';
cr.
library showActiveLoans.
library showBooks.
]