"====================================================================== 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.