Binstock on Software: Perfecting OO's Small Classes and Short Methods

The Pragmatic Programmersシリーズの新しい本、The ThoughtWorks Anthologyの中に

興味をそそるエッセイがある。Jeff Bayの"Object Calisthenics"だ。

これは良いオブジェクト指向の性質を実証する小さなルーチンを書く方法をマスターするための

詳細にわたるエクササイズだ。オブジェクト指向なルーチンを書く能力を向上させたい開発者がいるなら

このエッセイに目を通すことを勧める。ここにBayのアプローチを要約してみよう。

彼は次にあげられる制約のもとに1000行のプログラムを書くことを勧めている。

これらの制約は意図的に過剰な制限となっているが、これは開発者を手続き的なやり方から脱却させるためだ。

このテクニックを適用したらコードは顕著にオブジェクト指向よりになることを保証する。

この制限は次のものだ。

インデントは1メソッド1レベルのみ。2つ以上必要ならもう1つ別のメソッドを定義してそれを呼ぶようにする。これ重要。 'else'は禁止。条件文はifだけ。出来なければそのルーチンをexitすること。これでif-elseの連鎖を避けられて、1つのルーチンは1つのことだけをやるという状態を保てる。わかってきたね。 全部のプリミティブとstringをラップせよ。"primitive obsession."だ。整数型が使いたかったら、はじめにクラス(インナークラスでもいい)を作ってそれの本当の役割をはっきりさせる。たとえば郵便番号はオブジェクトで整数じゃないという具合に。これですっきりしてて、なおかつテストしやすいコードになる。 1行に1つのドットのみ使うこと。これで他のオブジェクトの深くまでいってフィールドやメソッドにアクセスするってことを避ける。こうしちゃうとカプセル化を破ることになってしまうから。 名前は省略しない。ある種の余計なものによって手続き的な冗長さできることを避けるためだ。もしメソッドや変数のフルネームをタイプしないといけないんだったら、きっともっと時間をかけて名前について考えるだろう。それによってshipOrder()というメソッドを持ったOrderなんてオブジェクトを作らなくなって代わりにOrder.ship()みたいな呼び出しが増えるはずだ。 エンティティを小さく保つこと。クラスは50行まで、パッケージごとに10クラスまで。1クラス50行までというのは極めて重要だ。これは簡潔さを強いてクラスをフォーカスさせるだけではなく、どんなエディタ/IDEでも1画面にクラスが収まることにもなる。 3つ以上のインスタンス変数を持ったクラスは使わないこと。きっとこれは一番難しいだろう。ここでの著者の考えは、2つのインスタンス変数があると、ほぼ必ずと言っていいほどそのいくつかの変数を別のクラスにサブグループかする道理があるってことだ。 ファーストクラスコレクションを使うこと。換言すればコレクションを持つクラスは他のメンバー変数を持つべきではない。primitive obsessionの拡張だ。コレクションを含んだクラスが必要なら、そういう風に書くんだ。 セッター、ゲッター、プロパティを使わない。これはカプセル化を強いる抜本的なアプローチだ。これはDependency Injectionアプローチの実装も必要になるし、"言え、訊くな"という格言の遵守も必要となる。

断言する。これらのルールを破らずに1000行のプロジェクト書いたものはOOがうまくなる。

よって望めば制限を和らげることも出来るようになる。でも作者が指摘するのはそうする理由はないということ。

彼のチームはちょうど100,000行のプロジェクトをこの制限のうちに終えたところなんだ。