ぷっちん日記
2012-03-05 (月) 呼び出し側から書く [長年日記]
■ 呼び出し側から書く
Rubyを使うようになってからのような気がするが、私は日頃、コードを「呼び出し側から書く」ようにしている。とても役に立つ手法だと思うので、ここで紹介したい。
例えば、勤務表から総役務時間を得たいとする。
このとき「ええと、勤務表である MonthlyWork クラスのインスタンスには日ごとに DailyWork があって、それらのうち実役務時間と有給休暇を足して... 」といったことを考えたりは *しない*。
「どうやってその機能を実現するか」を最初は考えないようにする。「本当にその機能を実現できるだろうか、不安だ」というような感情が襲ってくることもあるだろう(特に初心者には)。しかし、大概のことは最終的には実現できるし、もし本当に実現できない問題があったとすればそれは個人のせいではない。
「どうやってその機能を実現するか」を考え始める代わりに、私はまだ存在しないその機能を「呼び出してみる」。
具体的な手順はこうだ。Railsならばコントローラなりビューなり、そのメソッドを呼び出したい場所が「何処」であるかを考える。そして、そこに行って、こんなかんじで打ち込んでみるのである。
総役務時間: <%= monthly_work.total_work_time %>
このようにすることで、最初に考えることは次の3つに絞られる。
- どこから使うか
- 誰(どのオブジェクト)の仕事にするか
- どんな名前や引数で呼び出すか
この3つは、オブジェクト指向プログラミングにおける基本的かつ重要な設計事項である。ここをいい感じにすることにまず力を注ぐ。
もし、.を打ったあと手が止まってしまうようであれば、SPACEALCなどで調べたり、Googleで検索したり、チャットで意見をもらったりして、適切な言葉を探す。この段階でけっこう時間をかけることもある。
書いてみて、なにか格好悪く感じたり、気に入らなければ、心ゆくまで書き直す。いわば、自分の感性を利用して、I/F設計を練るわけだ。そして、納得のゆく呼び出し側コードを完成させる。
呼び出し方が決まったら、次は実装だ。今回のようなケースではこの後にスペック(単体テスト)を書いたりする。MonthlyWorkクラスのtotal_work_timeというメソッドとして実装することがもう決まっているので、スムーズに書き始めることができる。(逆に言えば、どのクラスのなんというメソッドにするかが不安定な状態で闇雲にスペックを書こうとするよりも、まずI/F設計に集中したほうがよい。テストファースト以前に設計ファーストだ。)
スペックを書いたらそれが通るように実装を行う。冒頭に挙げた「どのようにして総役務時間を計算するか」を考えるのはこのタイミングである。これより前に考える必要はない。ちなみに、実装中に、たとえば日単位のデータを持つ DailyWork に新しいメソッドが必要であるとわかったら、ここでもまず呼び出し側コードを書いて同様の手順で実装していく。
最終的に、スペックが通るようになったら、ブラウザを起動して、一番最初に書いたビューを表示する。ちゃんと動いているはずだ。
以上、「呼び出し側から書く」手法について書いてみた。日頃「書いたコードがどうもしっくり来ない」「この機能はどこに書くのが正解なのかな?」というような悩みを抱えている人の参考になればうれしい。