ベルリンのITスタートアップで働くジャバ・ザ・ハットリの日記

日本→シンガポール→ベルリンへと流れ着いたソフトウェアエンジニアのブログ

オブジェクト指向設計を実現するためのドMなコーディングルール

移転しました。

ちょっと古いブログだけど、オブジェクト指向設計を誰でもカンタンに実現するための4ルールを見つけた。
Sandi Metz' Rules For Developers

ブログ記事は「Practical Object-Oriented Design in Ruby」の著者が提唱しているコーディングルールをthoughtbot社が実践した、その結果。
(thoughtbot社って有名どころではFactory Girlとかのオープンソースプロジェクト持ってる会社ですな)

「Practical Object-Oriented Design in Ruby」を読んだ後であればルールの意味がよく分かる。
「手っ取り早くオブジェクト指向設計でコーディングしたい」と考えて予備知識無しに4ルールに従ってコードを書くと単なるMプレイにしかならないので私なりに解説した。

1) Classes can be no longer than one hundred lines of code.
クラス内のコードは100行まで

2) Methods can be no longer than five lines of code.
メソッドは5行まで

3) Pass no more than four parameters into a method. Hash options are parameters.
メソッドに渡す引数は4つまで。ハッシュのオプションもパラメータとカウントする。

4) Controllers can instantiate only one object. Therefore, views can only know about one instance variable and views should only send messages to that object
コントローラーがインスタンス化できるオブジェクトはひとつだけ。したがってViewが参照するオブジェクトはそのひとつだけでメッセージ送信もそのオブジェクトにだけ

(特別な場合はこのルールを少しだけ甘く見ることもある)


thoughtbot社ではこのルール実験による効果を検証し、結果はブログにあるように「Great success」と書いて成功したようだ。この後、同社のベストプラクティスルールにも組み込まれている。
guides/best-practices at master · thoughtbot/guides · GitHub



私なりのルール解説

1)クラス内のコードは100行まで
これは単一責任の原則にのとったルール。だいたいクラスのコードが100行を超えた時点でもうそれは単一責任でなくなってきている証拠。
「100行を越えたらダメ?」「別に1クラスに2,3個の責任をのせてナニが悪いの?」と考えた人へ。それやると後で再利用したり、コードを変更する時に複雑になりすぎて「アレ変えたらココも変えて」となる。この単一責任を守ってコーディングすることで、再利用可能でかつ可読性の高いオブジェクト指向設計が実現できる。コーディングにおいて「今、この瞬間にコードが動けばそれでOk。後のことは知らん」という発想から抜け出すためのルール。


2)メソッドは5行まで
これは最初はキツく感じるかもしれない。もしif-else-endを書いたらそれで3行。残りは2行。だからその間の処理はそれぞれ1行しか書き込めない。が、blog にあった例を見ると「あーなるほど」となる。

blogの例

def validate_actor
  if actor_type == 'Group'
    user_must_belong_to_group
  elsif actor_type == 'User'
    user_must_be_the_same_as_actor
  end
end

もうプライベートメソッドがほとんどコメントと同じぐらいの文章。要はプライベートメソッドを使って5行以内に収める。ひとつのメソッドでできるのはifの分岐がせいぜい。でも後でコード読む時にいちいちプライベートメソッドの中まで追いかける必要はない。だってメソッド名にuser_must_belong_to_groupって書いてあるから。

3)メソッドに渡す引数は4つまで。ハッシュのオプションもパラメータとカウントする
blogではこのルールはチャレンジングだと。で前述の「特別な場合は甘くみてね」ルールを適用した、とある。実際同社のベストプラクティスには含まれていない。私もこれはそこまで厳格に守るべきとは思わない。


4)コントローラーがインスタンス化できるオブジェクトはひとつだけ。したがってViewが参照するオブジェクトはそのひとつだけでメッセージ送信もそのオブジェクトにだけ
これはblogにもある通り、デザインパターンのFacadeを使うことでカンタンに実現できる。詳しくはFacadeパターンでググってください。


ルール3はともかくとして1,2,4を意識してコーディングすればそれなりにオブジェクト指向設計が実現できるはず。

ただこれらのルールはオブジェクト指向設計の考え型とそのメリットがあって出てきた結論でしかない。結論に至るまでの論理が頭に入ってなければ「このMプレイに意味あるの?」となる。そこは本読んで体系的に理解した方が近道。

日本で活躍するエンジニアに英語の本を紹介しても、あまり読んでいただけないのは承知の上。それでも紹介するのは私が海外でのエンジニア人生において、かろうじて面目を保っていられるのはこの本のおかげだから。翻訳版があればそれを紹介するが、無いので仕方がない。英語であっても内容はソフトウェアエンジニアとしてのレベルを2,3段あげてくれるオススメの本です。

tango-ruby.hatenablog.com

Practical Object-Oriented Design in Ruby: An Agile Primer (Addison-Wesley Professional Ruby Series)

Practical Object-Oriented Design in Ruby: An Agile Primer (Addison-Wesley Professional Ruby Series)