- 開発
READ MORE
原著者の許諾を得て翻訳・公開いたします。
Null Objectパターンによるリファクタリングは、指定されたオブジェクトが存在するかどうかをチェックして、存在しなかった場合に指定の属性やメソッドのデフォルト値を返す操作に適用できます。このような操作ではif
条件が必要になることが多く、そのままではコードが少々読みづらいうえにテストも少しばかりやりにくくなります。Null Objectパターンを使うことでコードが非常にシンプルになり、テストも簡単になります。
Null Objectパターンを使うメリットをわかりやすく示すため、次のような事例を考えてみましょう。User
とPost
という2つのクラスがあり、User
クラスのオブジェクトはPost
クラス上で操作を行います。
class User < ActiveRecord::Base
has_many :posts
def latest_post_title
post = posts.order('created_at DESC').first
if post.present?
post.title
else
"No posts yet"
end
end
end
「単一責任の原則」からほど遠いコードです。ここでは以下の操作を行っています。
post
をフェッチするpost
が存在するかどうかをチェックするpost
が存在する場合はpost
のtitle
を表示するpost
が存在しない場合は適切な情報を表示するこんなときはNull Objectパターンの出番です。まずは新しいオブジェクトを作成しましょう。
class NoPost
def title
"No posts yet"
end
end
シンプルなロジックを備えた、ごくシンプルなRubyオブジェクトができました。それではUser
モデルで以下を行ってリファクタリングしましょう。
NoPost
Null Objectを用いて、最新のpost
の代入を別のメソッドに切り出すpost
のtitle
を返す」シンプルな責務に変えるUser
クラスにこれらを実装すると、以下のように明快かつ読みやすいクラスに変わりました。
class User < ActiveRecord::Base
has_many :posts
def latest_post_title
lastest_post.title
end
private
def latest_post
find_latest_post || NoPost.new
end
def find_latest_post
posts.order('created_at DESC').first
end
end
User#latest_post_title
の内容が明快になり、if
条件も消滅しました。もうひとつ重要な点は、このNull Objectに適切な名前をつけて、何がしたいのかが名前からわかるようにすることです。
知りたいことがありましたら、twitter または連絡用フォームにてお気軽にお問い合わせください。
もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『Introduction Rails patterns』をどうぞお役立てください。