長いメソッドを分割するときのに行う方法を、今の開発メンバーへチャットで説明してみた。ホワイトボードとかがあればもう少し上手く説明できたと思うのだが、その環境が無いチャットで説明をしてみたのだ。
その時に話した内容が「メインメソッドでは大まかな処理を追える様にして、サブメソッドでは処理の詳細を記述して欲しい」と言うものだ。だけど、この説明では上手く可読性について伝わらず「大まかな処理って何」と言う状況になってしまった。
なので、僕は知恵を振り絞って話したのが「メインメソッドは目次である」と言う事を伝えた。これが上手い表現だったようで、僕の意図したことが伝わった。それで今回はこの話をネタにしてしまおうと思う。
そもそもコードの可読性を良くすると言うのは、読み手に依存するため正解はありません。フレームワークの決まりや言語の決まりに沿っていればある程度の可読性は保障されます。
しかし、実際にアプリケーションを作成した場合にフレームワークの決まりや言語の決まりに沿っていても可読性が悪いことがあります。それが
長いコード
です。オブジェクト指向では「一つのメソッドに記載するコードは20行」と言う推奨があります。(CheckStyleでは50行以上のメソッドには警告を表示するなんて現場も多々あるくらいです。)ですので、長いコードはメソッド化して分けなければなりません。
では、実際にはどうやって長いコードを分けるのが良いのでしょうか?適当に分けてしまえば良いのでしょうか?
簡単にテクニックを紹介するとこんな感じになります。
1.再利用可能部品毎にメソッド分けを行う。
大原則としてはこの通りです。ただし、どれもこれも再利用可能であることは無いため必ず使えるテクニックではない。また、再利用可能であるかどうかを検討する必要も出てくる。(将来的に再利用可能だと思うというレベルならばメソッド化しないほうが良い場合もある。)
2.疎結合と密結合を意識してメソッド分けを行う。
疎結合とは、メソッド同士/オブジェクト同士の関連性が薄いものを言います。密結合は逆で関連性の濃いものを言います。密結合になればなるほど生産性は上がりやすく、保守性が下がります。なので、可読性を求める場合は疎結合としてメソッド分割出来る物を洗い出すことが良いと言えます。このテクニックは可読性を浴する際には必須のテクニックとなります。
しかし、これのテクニックは必須ですが可読性が必ず上がるというものではありません。
結局の所これらはテクニックであるため、王道の技術ではありません。テクニックは本筋を学んでから使えばよいのです。では、本筋はどのようなものでしょうか?
僕の答えが「目次」だったのです。
プログラムを書くことと文章を書くことは似ています。長い文章を書いた場合は、ピンポイントで読みたい文章を表示したいと思います。そのためにあるのが目次になるのです。
プログラムでも同様のことが言えます。メインメソッドでは制御系のコードのみを書いて、実際の処理はサブメソッドに任せるということです。
rubyで例を書くとこうなる。
--------------
def edit
# POST処理であるかチェックする。
if request.post?
# POSTされた場合の共通処理
common
# ボタン制御
if params[:back]
# 戻るボタンの処理
back
else
# 更新処理
update
end
else
# データ表示処理
show
end
end
private:
# POSTされた場合の共通処理
def common
・
・
・
end
# 戻るボタンの処理
def back
・
・
・
end
# 更新処理
def update
・
・
・
end
# データ表示処理
def show
・
・
・
end
--------------
(デザインパターン{ポリモルフィズム系}を使ってIF文を回避すると言う手もありますが、業務ロジックではあまり使わないので紹介はしません。)
このように記述することによって、editメソッドの目次は出来上がりとなります。このように記述することによって、自分の読みたい処理だけがIF文を追って読むことが出来るのです。
このような切り分け方をすれば1メソッド20行以内で読みやすいコードが出来上がるのです。
P.S.
Rubyはこういうときのサンプルを書きやすい言語だ。言語自体がシンプルに出来ているのだろう。
こんな話をリアルにしたい方は是非
へ来てください!
※交流会の締切日です。