1.はじめに
最近、Rubyでオブジェクト指向を学び始めたのですが、頭の中で整理されておらず苦労した点も多かったので、今回は実際に簡単な書籍管理システムをオブジェクト指向を使用しながら実装し、復習していきたいと思います。
2.書籍管理システムを実装していく
今回、作成するシステムのイメージとしては、システムに登録されている書籍のタイトルを入力するとその書籍の情報が表示されるようなシステムにしていきます。
(1) クラスの定義
ここでは神戸市の図書館にあるシステムを想定して、実装をしていきます。
クラスはLibraryクラスとBookクラスを作成し、以下のような役割のイメージを持ちます。
クラス | 役割 | 属性・データ | メソッド・振る舞い |
---|---|---|---|
Library | システムとしての動作 |
|
|
Book | 書籍情報の把握 |
|
|
Libraryクラス
- 書籍管理システムのLibraryクラスを宣言する。
- 検索ボタンを押すと、書籍が表示されるようにする。
ここではsearch_buttonメソッド実行すると、「半沢直樹」が表示されるようにしていきましょう!
(半沢直樹のドラマにハマりすぎて、ドラマが終わってしまったときは半沢直樹ロスになっていました...笑)
class Library
def search_button
'半沢直樹'
end
end
kobe_library = Library.new
kobe_library.serch_button
半沢直樹
Bookクラス
- 書籍情報が入っているBookクラスを宣言する。
- infoメソッドを実行すると、タイトル・著者・発行年が表示されるようにする。
class Book
def info
"タイトル:半沢直樹, 著者:池井戸潤, 発行年:2004"
end
end
book1 = Book.new
book1.info
タイトル:半沢直樹, 著者:池井戸潤, 発行年:2004
(2) initializeメソッドを追記
インスタンスを初期化するために実行したい処理をinitializeメソッドに実装していきます。
Libraryクラス
- システムに書籍を登録していくために空配列が用意されたbooks変数を定義する。
- books変数は同じインスタンスの内部で共有して使用したいので、「@」を先頭に付けインスタンス変数として定義する。
class Library
def initialize
@books = []
end
end
Bookクラス
- インスタンス生成時にその本のタイトル・著者・発行年をインスタンス変数に持たせる。
本によってデータが変わるためinitializeメソッドに引数をつけ、newメソッドでインスタンスを生成するときにも引数が必要となることに注意する。 - infoメソッドをインスタンス変数を用いて定義する。
class Book
def initialize(title, author, publication_year)
@title = title
@author = author
@publication_year = publication_year
end
def info
"タイトル:#{@title}, 著者:#{@author}, 発行年:#{@publication_year}"
end
end
book1 = Book.new('半沢直樹', '池井戸潤', 2004)
book1.info
タイトル:半沢直樹, 著者:池井戸潤, 発行年:2004
(3) アクセスメソッドの追記
attr_readerメソッドを用いて、インスタンス変数へのアクセス(取得)を簡単にしておきましょう。
また、今回は読み込みのみを想定しているためattr_readerメソッドですが、外部からインスタンス変数の内容を変更できるようにしたい場合はattr_writerメソッド、読み込み書き込みの両方できるようにしたい場合はattr_accessorメソッドを用います。
Libraryクラス
class Library
attr_reader :books
# 省略
end
Bookクラス
試しにインスタンス変数の@authorに何が入っているか読み込んでみましょう。
class Book
attr_reader :title, :author, :publication_year
# 省略
end
book1 = Book.new('半沢直樹', '池井戸潤', 2004)
book1.author
池井戸潤
きちんと読み込めていました(^^)
(4)【機能①】新しい書籍をシステムへ追加する
Bookクラスで作成されたインスタンスをLibraryクラスのインスタンス変数@booksへ追加していくadd_bookメソッドをここで追加していきましょう。
Libraryクラス
- add_bookメソッドの引数にBookクラスで作成されたインスタンスを渡し、空配列の@booksに追加していく。
class Library
# 省略
def add_book(book)
@books << book
end
end
kobe_library = Library.new
book1 = Book.new('半沢直樹', '池井戸潤', 2004)
# 本の追加
kobe_library.add_book(book1)
kobe_library.books
#<Book:0x0000000102509288>
出力画面にはBookクラスのインスタンスが表示されているので、add_bookメソッドによりインスタンス変数@booksに追加されていることが確認できました!
(5)【機能②】システム上の全ての書籍を表示する
次にシステムに登録されている全ての書籍を表示させるlist_booksメソッドを追加していきます。
Libraryクラス
- list_booksメソッドでは配列@booksをeachメソッドを用いて順番に要素を取り出しながらbookのinfoメソッドで書籍情報を表示させる。
class Library
# 省略
def list_books
@books.each { |book| puts book.info }
end
end
kobe_library = Library.new
book1 = Book.new('半沢直樹', '池井戸潤', 2004)
book2 = Book.new('君の膵臓をたべたい', '住野よる', 2015)
# 本の追加
kobe_library.add_book(book1)
kobe_library.add_book(book2)
# 全ての本を表示
kobe_library.list_books
タイトル:半沢直樹, 著者:池井戸潤, 発行年:2004
タイトル:君の膵臓をたべたい, 著者:住野よる, 発行年:2015
出力画面にadd_bookメソッドで登録した書籍が表示されているので、list_booksメソッドの挙動が正しいことが確認できました。
(6)【機能③】書籍名で検索できるようにする
最後に書籍名だけ把握している場合に、その書籍の情報を検索できるようなfind_bookメソッドを実装していきましょう。
Libraryクラス
- find_bookメソッドでは、配列@booksをfindメソッドを用いて順番に要素を取り出しながら、bookのインスタンス変数titleが引数のtitleと一致したときに戻り値を真で返し、そのときの最初の要素を取り出す。
- find_bookメソッドの戻り値はBookクラスのインスタンスであるので書籍の情報を表示させるinfoメソッドの使用が可能である。
class Library
# 省略
def find_book(title)
@books.find { |book| book.title = title }
end
end
kobe_library = Library.new
book1 = Book.new('半沢直樹', '池井戸潤', 2004)
book2 = Book.new('君の膵臓をたべたい', '住野よる', 2015)
# 本の追加
kobe_library.add_book(book1)
kobe_library.add_book(book2)
# タイトルだけ分かっている書籍を検索
found_book = kobe_library.find_book('君の膵臓をたべたい')
puts "検索結果→#{found_book.info}"
検索結果→タイトル:君の膵臓をたべたい, 著者:住野よる, 発行年:2015
出力画面に検索結果が表示されましたので、無事実装できました!
3.おわりに
オブジェクト指向を学び始めましたが、雲を掴むような話でなかなか理解できておらず知識も浅いですが、今回のように何かサービスを作りながら学ぶのが頭に入ってきやすいなと感じました(^^)
オブジェクト指向にはここに載せれてない技術が他にもたくさんありますので、そちらも地道に勉強して慣れていきたいです!