ジャバ・ザ・ハットリ
Published on

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

Authors
  • avatar
    ジャバ・ザ・ハットリ

ちょっと古いブログだけど、オブジェクト指向設計を誰でもカンタンに実現するための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段あげてくれるオススメの本です。

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)
作者: Sandi Metz
出版社/メーカー: Addison-Wesley Professional
発売日: 2012/09/05
メディア: Kindle 版