インデントは1段階

ThoughtWorksアンソロジーに載っているエッセイに、「オブジェクト指向エクササイズ」があります。
これに書かれている「9つのルール」がとても興味深いものです。
これを実践するだけで、コード領域についてはかなりよくなるのではないか?という予感があります。
まず「9つのルール」を以下にあげてみましょう。

  1. 1つのメソッドにつきインデントは1段階までにすること
  2. else句を使用しないこと
  3. すべてのプリミティブ型と文字列型をラップすること
  4. 1行につきドットは1つまでにすること
  5. 名前を省略しないこと
  6. すべてのエンティティを小さくすること
  7. 1つのクラスにつきインスタンス変数は2つまでにすること
  8. ファーストクラスコレクションを使用すること
  9. Getter、Setter、プロパティを使用しないこと

ざっと見てみると、センセーショナルに思う内容もあるのではないでしょうか?
では、まず1の「1つのメソッドにつきインデントは1段階までにすること」について書いてみましょう。

このルールの目的は、メソッドの仕事をシンプルにして、コード簡潔にすることです。

「インデントが一段階」ということは、制御構造(ループや分岐)が一つということです。
例えば、メソッドの中にforループがネストしているようなコードはNGです。
ThoughtWorksアンソロジーに載っているサンプルもそうですね。

そのようなコードをリファクタリング手法のメソッドの抽出等を使い、インデントが1段階になるまで抜き出します。
今時はEclipseなどのIDEが進歩しているので、このような作業もかなり簡単になりました。

リファクタリングの第一歩には、このルールの適用が最適な気がしますね。
このルールでまずはメソッドを抽出し、新たなクラスを発見し、メソッドを移動する。
これを繰り返していくだけで、クラスもメソッドも小さくなりコードの保守性があがりそうです。

発見するためには?

アジャイルな開発での「発見」について書いてみます。

「発見する」シーン

アジャイルなプロジェクトでは「発見」と「フィードバック」が大きなカギになります。
「発見」→「フィードバック」が発生するシーンの例を挙げてみましょう。

  1. ストーリーカードを元に顧客と要件を掘り下げていったら、ストーリーが大きくなりすぎていることに気づいた
  2. ICONIXプロセスの要求レビューをしたら、新たなドメインモデルを発見した

1の例は、顧客が書いたストーリーカードを元に話を聞き、工数を見積もったり、処理イメージを出すようなシーンです。一緒に話していくうちに新たなストーリーを話し出したり、複数のストーリーにしたほうが取り扱いやすいことに気づいたりします。ここで大事なのは気づくことです。この場合、「違うストーリーの話だ」「分けたほうがよさそうだ」と気づくことができれば、

「その話はこれとは別のストーリーとして話しましょう。簡単にストーリーを書いてもらえますか?」

とか、

「ストーリーがひとつで取り扱うには大きすぎるようです。ストーリーを分けますね。」

というような感じで顧客にフィードバックして、上手に話しをすすめていくことができます。それができない場合、顧客との認識にギャップが生じたり、取り扱いにくいストーリーができてしまうことになります。

「発見できない」ケース

「見つかったものをフィードバックしない」ケースの多くは、
「見つかったことに気づかない」ケースが多いように思います。

1の例で言うと、ストーリーが違う話に変わったり、掘り下げるうちに違うストーリーが出てきているのに、そのまま見過ごしてしまうような場合です。

このような場合には、今何について話しているのか明確に意識していれば、話が変わったことや違うストーリーが出てきたところで、何かしらの違和感を感じるでしょう。そのためには、取り扱っているドメインに対してある程度の理解も必要かもしれません。

2の例で言うと、要求レビュー中に顧客が何の気なしに発言した単語が実はドメインモデルに組み入れるべきものだったりします。何の気なしに発言しているので、顧客も自分達も、その重要さに気づきません。

ですが、「ユビキタス言語で話す・聞く」ということを意識していれば、ユビキタス言語にない単語について、何かしらの違和感が生じるはずです。その違和感の正体がわかれば、

「その単語は重要そうです。詳しく聞かせてください」

というように、フィードバックしながらすすめていくことができるでしょう。

違和感を大事にする

大事なのは、

・取り扱うドメインに対して、少なくともある程度の理解をもつ
→そもそも顧客の話を理解するために、最低限理解すべき知識があるはず。ユビキタス言語が成り立つ前提かな?

・「ユビキタス言語で話す、聞く」意識を持つ
→「ユビキタス言語」にない言葉には違和感があるはず。そういう言葉には敏感に反応する。

・関心を分離して、今自分達が何について話しているのか明確に意識する
→顧客の関心がブレたら要注意。一旦置いておくか、入り込むかをジャッジする。(もちろん、自分もブレないこと。)

というところでしょうか。
これらを実践すれば、顧客との話やレビュー中に「違和感」として感じ取ることができるはずです。その「違和感」を見過ごさないで追跡していけば、「発見」することができるでしょう。

基本はフィードバック

アジャイルな開発プロセスで大事なのは、フィードバックすることです。
フィードバックする・されるということは、自分以外の何か(人や設計)とシンクロしながら進むということです。
XPで言うと、

  • ペアプログラミングではナビゲーターとドライバーが一緒に考えて、コミュニケートしながらプログラミングをする
  • オンサイト顧客とコミュニケートしながらストーリーカードを具体化する

なんていうことが該当します。とにかくコミュニケーションすることで、お互いにフィードバックしながら進むのがXPのスタイル。

XPに限らず、アジャイルな開発に共通して言えることは、工程の初めから全てを見通して進んでいるわけではないということ。
アジャイルなプロセスでは、途中でいろんなことを発見しながら進み、見つかったことをフィードバックしていきます。
私たちが今実行中のICONIXプロセスについても、同じことが言えますね。

ドメインモデリング→ユースケース→ロバストネス分析・・・と進んでいきますが、その途中でいろんなものが見つかります。

たとえば、

  1. ユースケースを記述している最中にドメインモデルが見つかる。(見つかったら、ドメインモデルのダイアグラムに追加する。)
  2. ユースケースを記述している最中に、要求が見つかる。(見つかったら、要求に書き足して、ユースケースに関連付けておく。)
  3. ロバストネス分析をしている最中に、代替ケースが見つかる(見つかったら、ユースケース記述に書き足す)

といった具合です。

実は、ここでエンジニアがフィードバックを怠っても、コードは作成される場合もあります。
でも、「コードができればいいじゃん」的なノリで進むと、実は痛い目に会います。
たとえば、1.の場合にはドメインモデルが足りなくなる。
ドメインモデルは、互いの理解の共通語彙であるので、自分以外のエンジニアや顧客とのコミュニケーションに支障をきたす恐れがある。
また、せっかく発見したのにドメインモデルがないと、へんなクラスにメソッドを割り当ててしまうこともあるでしょう。

2.の場合には、顧客の理解が不足し、受入テストのケースが落ちてしまう可能性が高いです。
要件定義のフェーズでは、全ての要求は出ていないと思ったほうがまちがいないでしょう。
ユースケースを書いているときには、本当によく要求が見つかります。

3.の場合には、やはりコードから代替ケースが落ちる可能性があります。
コードはできたとしても、システムテストのケースからは落ちてしまいそうです。
ICONIXプロセスは、「設計する」ことをとても大事にしていると思います。コードだけではなく、テストも設計駆動なので、
設計へのフィードバックを怠ると、テストも不十分になってしまいます。

ICONIXプロセスに推奨ツールがあるのは、機能面もさることながら、フィードバックの容易性も考えてのことだと考えています。
設計リポジトリを共有し、ほぼ全てを設計できるツールを用いて、何かを見つけたらすぐにフィードバックする。
そういう良いクセを習慣づけて、速く、良いソフトウェアを作れるようになっていきたいものです。