fork download
  1. "============================================================"
  2. " 大学図書館貸出システム"
  3. " Ideone / GNU Smalltalk向け"
  4. "============================================================"
  5.  
  6.  
  7. "------------------------------------------------------------"
  8. " Book:図書"
  9. "------------------------------------------------------------"
  10.  
  11. Object subclass: #Book
  12. instanceVariableNames: 'isbn title author available'
  13. classVariableNames: ''
  14. poolDictionaries: ''
  15. category: 'UniversityLibrary'!
  16.  
  17.  
  18. !Book class methodsFor: 'instance creation'!
  19.  
  20. isbn: anISBN title: aTitle author: anAuthor
  21. ^self new
  22. initializeISBN: anISBN
  23. title: aTitle
  24. author: anAuthor
  25. !
  26.  
  27. !
  28.  
  29.  
  30. !Book methodsFor: 'initialization'!
  31.  
  32. initializeISBN: anISBN title: aTitle author: anAuthor
  33. isbn := anISBN.
  34. title := aTitle.
  35. author := anAuthor.
  36. available := true.
  37. ^self
  38. !
  39.  
  40. !
  41.  
  42.  
  43. !Book methodsFor: 'accessing'!
  44.  
  45. isbn
  46. ^isbn
  47. !
  48.  
  49. title
  50. ^title
  51. !
  52.  
  53. author
  54. ^author
  55. !
  56.  
  57. isAvailable
  58. ^available
  59. !
  60.  
  61. !
  62.  
  63.  
  64. !Book methodsFor: 'loan operations'!
  65.  
  66. borrow
  67. available
  68. ifFalse: [self error: 'この図書はすでに貸出中です'].
  69.  
  70. available := false
  71. !
  72.  
  73. returnBook
  74. available
  75. ifTrue: [self error: 'この図書は貸出されていません'].
  76.  
  77. available := true
  78. !
  79.  
  80. !
  81.  
  82.  
  83. !Book methodsFor: 'printing'!
  84.  
  85. printOn: aStream
  86. aStream
  87. nextPutAll: title;
  88. nextPutAll: ' / ';
  89. nextPutAll: author;
  90. nextPutAll: ' [ISBN: ';
  91. nextPutAll: isbn;
  92. nextPutAll: ']'.
  93.  
  94. available
  95. ifTrue: [aStream nextPutAll: ' 貸出可能']
  96. ifFalse: [aStream nextPutAll: ' 貸出中']
  97. !
  98.  
  99. !
  100.  
  101.  
  102. "------------------------------------------------------------"
  103. " Member:図書館利用者"
  104. "------------------------------------------------------------"
  105.  
  106. Object subclass: #Member
  107. instanceVariableNames: 'memberId name memberType'
  108. classVariableNames: ''
  109. poolDictionaries: ''
  110. category: 'UniversityLibrary'!
  111.  
  112.  
  113. !Member class methodsFor: 'instance creation'!
  114.  
  115. id: anId name: aName type: aType
  116. ^self new
  117. initializeId: anId
  118. name: aName
  119. type: aType
  120. !
  121.  
  122. !
  123.  
  124.  
  125. !Member methodsFor: 'initialization'!
  126.  
  127. initializeId: anId name: aName type: aType
  128. memberId := anId.
  129. name := aName.
  130. memberType := aType.
  131. ^self
  132. !
  133.  
  134. !
  135.  
  136.  
  137. !Member methodsFor: 'accessing'!
  138.  
  139. memberId
  140. ^memberId
  141. !
  142.  
  143. name
  144. ^name
  145. !
  146.  
  147. memberType
  148. ^memberType
  149. !
  150.  
  151. loanLimit
  152. memberType = #student
  153. ifTrue: [^3].
  154.  
  155. memberType = #teacher
  156. ifTrue: [^10].
  157.  
  158. ^2
  159. !
  160.  
  161. loanPeriod
  162. memberType = #teacher
  163. ifTrue: [^30].
  164.  
  165. ^14
  166. !
  167.  
  168. typeName
  169. memberType = #student
  170. ifTrue: [^'学生'].
  171.  
  172. memberType = #teacher
  173. ifTrue: [^'教職員'].
  174.  
  175. ^'その他'
  176. !
  177.  
  178. !
  179.  
  180.  
  181. !Member methodsFor: 'printing'!
  182.  
  183. printOn: aStream
  184. aStream
  185. nextPutAll: name;
  186. nextPutAll: ' [利用者番号: ';
  187. nextPutAll: memberId;
  188. nextPutAll: ', 区分: ';
  189. nextPutAll: self typeName;
  190. nextPutAll: ']'
  191. !
  192.  
  193. !
  194.  
  195.  
  196. "------------------------------------------------------------"
  197. " Loan:貸出記録"
  198. " 日付は、例を簡単にするため整数の日数で表現する"
  199. "------------------------------------------------------------"
  200.  
  201. Object subclass: #Loan
  202. instanceVariableNames: 'book member loanDay dueDay returnedDay'
  203. classVariableNames: ''
  204. poolDictionaries: ''
  205. category: 'UniversityLibrary'!
  206.  
  207.  
  208. !Loan class methodsFor: 'instance creation'!
  209.  
  210. book: aBook member: aMember loanDay: aLoanDay
  211. ^self new
  212. initializeBook: aBook
  213. member: aMember
  214. loanDay: aLoanDay
  215. !
  216.  
  217. !
  218.  
  219.  
  220. !Loan methodsFor: 'initialization'!
  221.  
  222. initializeBook: aBook member: aMember loanDay: aLoanDay
  223. book := aBook.
  224. member := aMember.
  225. loanDay := aLoanDay.
  226. dueDay := aLoanDay + member loanPeriod.
  227. returnedDay := nil.
  228. ^self
  229. !
  230.  
  231. !
  232.  
  233.  
  234. !Loan methodsFor: 'accessing'!
  235.  
  236. book
  237. ^book
  238. !
  239.  
  240. member
  241. ^member
  242. !
  243.  
  244. loanDay
  245. ^loanDay
  246. !
  247.  
  248. dueDay
  249. ^dueDay
  250. !
  251.  
  252. returnedDay
  253. ^returnedDay
  254. !
  255.  
  256. isActive
  257. ^returnedDay isNil
  258. !
  259.  
  260. isOverdueOn: currentDay
  261. ^self isActive and: [currentDay > dueDay]
  262. !
  263.  
  264. !
  265.  
  266.  
  267. !Loan methodsFor: 'returning'!
  268.  
  269. returnOn: aDay
  270. self isActive
  271. ifFalse: [self error: 'この貸出記録はすでに返却済みです'].
  272.  
  273. returnedDay := aDay.
  274. book returnBook
  275. !
  276.  
  277. !
  278.  
  279.  
  280. !Loan methodsFor: 'printing'!
  281.  
  282. printOn: aStream
  283. aStream
  284. nextPutAll: member name;
  285. nextPutAll: ' -> ';
  286. nextPutAll: book title;
  287. nextPutAll: ' / 貸出日: ';
  288. print: loanDay;
  289. nextPutAll: ' / 返却期限: ';
  290. print: dueDay.
  291.  
  292. self isActive
  293. ifTrue: [aStream nextPutAll: ' / 貸出中']
  294. ifFalse: [
  295. aStream
  296. nextPutAll: ' / 返却日: ';
  297. print: returnedDay
  298. ]
  299. !
  300.  
  301. !
  302.  
  303.  
  304. "------------------------------------------------------------"
  305. " Library:大学図書館"
  306. "------------------------------------------------------------"
  307.  
  308. Object subclass: #Library
  309. instanceVariableNames: 'name books members loans'
  310. classVariableNames: ''
  311. poolDictionaries: ''
  312. category: 'UniversityLibrary'!
  313.  
  314.  
  315. !Library class methodsFor: 'instance creation'!
  316.  
  317. named: aName
  318. ^self new initializeName: aName
  319. !
  320.  
  321. !
  322.  
  323.  
  324. !Library methodsFor: 'initialization'!
  325.  
  326. initializeName: aName
  327. name := aName.
  328. books := OrderedCollection new.
  329. members := OrderedCollection new.
  330. loans := OrderedCollection new.
  331. ^self
  332. !
  333.  
  334. !
  335.  
  336.  
  337. !Library methodsFor: 'registration'!
  338.  
  339. addBook: aBook
  340. (self findBookByISBN: aBook isbn) notNil
  341. ifTrue: [self error: '同じISBNの図書が登録されています'].
  342.  
  343. books add: aBook
  344. !
  345.  
  346. registerMember: aMember
  347. (self findMemberById: aMember memberId) notNil
  348. ifTrue: [self error: '同じ利用者番号が登録されています'].
  349.  
  350. members add: aMember
  351. !
  352.  
  353. !
  354.  
  355.  
  356. !Library methodsFor: 'searching'!
  357.  
  358. findBookByISBN: anISBN
  359. books do: [:each |
  360. each isbn = anISBN
  361. ifTrue: [^each]
  362. ].
  363.  
  364. ^nil
  365. !
  366.  
  367. findMemberById: anId
  368. members do: [:each |
  369. each memberId = anId
  370. ifTrue: [^each]
  371. ].
  372.  
  373. ^nil
  374. !
  375.  
  376. findBooksByTitle: aKeyword
  377. | result |
  378.  
  379. result := OrderedCollection new.
  380.  
  381. books do: [:each |
  382. (each title includesSubString: aKeyword)
  383. ifTrue: [result add: each]
  384. ].
  385.  
  386. ^result
  387. !
  388.  
  389. activeLoansFor: aMember
  390. | result |
  391.  
  392. result := OrderedCollection new.
  393.  
  394. loans do: [:each |
  395. (each member == aMember and: [each isActive])
  396. ifTrue: [result add: each]
  397. ].
  398.  
  399. ^result
  400. !
  401.  
  402. activeLoanForBook: aBook
  403. loans do: [:each |
  404. (each book == aBook and: [each isActive])
  405. ifTrue: [^each]
  406. ].
  407.  
  408. ^nil
  409. !
  410.  
  411. !
  412.  
  413.  
  414. !Library methodsFor: 'loan operations'!
  415.  
  416. lendISBN: anISBN toMember: anId onDay: aDay
  417. | book member activeLoans loan |
  418.  
  419. book := self findBookByISBN: anISBN.
  420. book isNil
  421. ifTrue: [self error: '指定された図書が見つかりません'].
  422.  
  423. member := self findMemberById: anId.
  424. member isNil
  425. ifTrue: [self error: '指定された利用者が見つかりません'].
  426.  
  427. book isAvailable
  428. ifFalse: [self error: '指定された図書は貸出中です'].
  429.  
  430. activeLoans := self activeLoansFor: member.
  431.  
  432. activeLoans size >= member loanLimit
  433. ifTrue: [self error: '貸出可能冊数を超えています'].
  434.  
  435. book borrow.
  436.  
  437. loan := Loan
  438. book: book
  439. member: member
  440. loanDay: aDay.
  441.  
  442. loans add: loan.
  443.  
  444. ^loan
  445. !
  446.  
  447. returnISBN: anISBN onDay: aDay
  448. | book loan |
  449.  
  450. book := self findBookByISBN: anISBN.
  451. book isNil
  452. ifTrue: [self error: '指定された図書が見つかりません'].
  453.  
  454. loan := self activeLoanForBook: book.
  455. loan isNil
  456. ifTrue: [self error: 'この図書の有効な貸出記録がありません'].
  457.  
  458. loan returnOn: aDay.
  459.  
  460. ^loan
  461. !
  462.  
  463. !
  464.  
  465.  
  466. !Library methodsFor: 'reporting'!
  467.  
  468. showBooks
  469. Transcript
  470. cr;
  471. show: '===== 図書一覧 =====';
  472. cr.
  473.  
  474. books do: [:each |
  475. Transcript
  476. show: each printString;
  477. cr
  478. ]
  479. !
  480.  
  481. showMembers
  482. Transcript
  483. cr;
  484. show: '===== 利用者一覧 =====';
  485. cr.
  486.  
  487. members do: [:each |
  488. Transcript
  489. show: each printString;
  490. cr
  491. ]
  492. !
  493.  
  494. showActiveLoans
  495. Transcript
  496. cr;
  497. show: '===== 現在の貸出一覧 =====';
  498. cr.
  499.  
  500. loans do: [:each |
  501. each isActive
  502. ifTrue: [
  503. Transcript
  504. show: each printString;
  505. cr
  506. ]
  507. ]
  508. !
  509.  
  510. showOverdueLoansOn: currentDay
  511. Transcript
  512. cr;
  513. show: '===== 延滞一覧 =====';
  514. cr.
  515.  
  516. loans do: [:each |
  517. (each isOverdueOn: currentDay)
  518. ifTrue: [
  519. Transcript
  520. show: each printString;
  521. show: ' / 延滞日数: ';
  522. show: (currentDay - each dueDay) printString;
  523. cr
  524. ]
  525. ]
  526. !
  527.  
  528. !
  529.  
  530.  
  531. "============================================================"
  532. " 実行例"
  533. "============================================================"
  534.  
  535. Eval [
  536. | library book1 book2 book3 student teacher loan1 loan2 |
  537.  
  538. library := Library named: '○○大学図書館'.
  539.  
  540. "図書を作成"
  541.  
  542. book1 := Book
  543. isbn: '978-4-00-000001-1'
  544. title: 'Smalltalk入門'
  545. author: '山田太郎'.
  546.  
  547. book2 := Book
  548. isbn: '978-4-00-000002-8'
  549. title: 'オブジェクト指向設計'
  550. author: '佐藤花子'.
  551.  
  552. book3 := Book
  553. isbn: '978-4-00-000003-5'
  554. title: 'データベース基礎'
  555. author: '鈴木一郎'.
  556.  
  557. "利用者を作成"
  558.  
  559. student := Member
  560. id: 'S2023001'
  561. name: '田中学生'
  562. type: #student.
  563.  
  564. teacher := Member
  565. id: 'T1001'
  566. name: '佐々木教授'
  567. type: #teacher.
  568.  
  569. "図書を登録"
  570.  
  571. library addBook: book1.
  572. library addBook: book2.
  573. library addBook: book3.
  574.  
  575. "利用者を登録"
  576.  
  577. library registerMember: student.
  578. library registerMember: teacher.
  579.  
  580. Transcript
  581. show: '大学図書館貸出システムを開始します';
  582. cr.
  583.  
  584. library showBooks.
  585. library showMembers.
  586.  
  587. "100日目に学生が借りる"
  588.  
  589. loan1 := library
  590. lendISBN: '978-4-00-000001-1'
  591. toMember: 'S2023001'
  592. onDay: 100.
  593.  
  594. Transcript
  595. cr;
  596. show: '貸出処理: ';
  597. show: loan1 printString;
  598. cr.
  599.  
  600. "105日目に教職員が借りる"
  601.  
  602. loan2 := library
  603. lendISBN: '978-4-00-000002-8'
  604. toMember: 'T1001'
  605. onDay: 105.
  606.  
  607. Transcript
  608. show: '貸出処理: ';
  609. show: loan2 printString;
  610. cr.
  611.  
  612. library showActiveLoans.
  613. library showBooks.
  614.  
  615. "120日目時点の延滞を確認"
  616.  
  617. library showOverdueLoansOn: 120.
  618.  
  619. "学生が121日目に返却"
  620.  
  621. library
  622. returnISBN: '978-4-00-000001-1'
  623. onDay: 121.
  624.  
  625. Transcript
  626. cr;
  627. show: 'Smalltalk入門を返却しました';
  628. cr.
  629.  
  630. library showActiveLoans.
  631. library showBooks.
  632. ]
Success #stdin #stdout 0.01s 9756KB
stdin
Standard input is empty
stdout
大学図書館貸出システムを開始します

===== 図書一覧 =====
Smalltalk入門 / 山田太郎 [ISBN: 978-4-00-000001-1] 貸出可能
オブジェクト指向設計 / 佐藤花子 [ISBN: 978-4-00-000002-8] 貸出可能
データベース基礎 / 鈴木一郎 [ISBN: 978-4-00-000003-5] 貸出可能

===== 利用者一覧 =====
田中学生 [利用者番号: S2023001, 区分: 学生]
佐々木教授 [利用者番号: T1001, 区分: 教職員]

貸出処理: 田中学生 -> Smalltalk入門 / 貸出日: 100 / 返却期限: 114 / 貸出中
貸出処理: 佐々木教授 -> オブジェクト指向設計 / 貸出日: 105 / 返却期限: 135 / 貸出中

===== 現在の貸出一覧 =====
田中学生 -> Smalltalk入門 / 貸出日: 100 / 返却期限: 114 / 貸出中
佐々木教授 -> オブジェクト指向設計 / 貸出日: 105 / 返却期限: 135 / 貸出中

===== 図書一覧 =====
Smalltalk入門 / 山田太郎 [ISBN: 978-4-00-000001-1] 貸出中
オブジェクト指向設計 / 佐藤花子 [ISBN: 978-4-00-000002-8] 貸出中
データベース基礎 / 鈴木一郎 [ISBN: 978-4-00-000003-5] 貸出可能

===== 延滞一覧 =====
田中学生 -> Smalltalk入門 / 貸出日: 100 / 返却期限: 114 / 貸出中 / 延滞日数: 6

Smalltalk入門を返却しました

===== 現在の貸出一覧 =====
佐々木教授 -> オブジェクト指向設計 / 貸出日: 105 / 返却期限: 135 / 貸出中

===== 図書一覧 =====
Smalltalk入門 / 山田太郎 [ISBN: 978-4-00-000001-1] 貸出可能
オブジェクト指向設計 / 佐藤花子 [ISBN: 978-4-00-000002-8] 貸出中
データベース基礎 / 鈴木一郎 [ISBN: 978-4-00-000003-5] 貸出可能