リファクタリングは設計の代わりにはならないよ

InfoQ: Refactoring Not a Substitute for Design

リファクタリングは設計の代わりにはならないよ
2009年2月9日 Chris Sims

「設計ってリファクタリングの一部なの?」という質問を受けた。この質問の背景には、Agileにおける設計の考え方に関する勘違いが見受けられる。よくAgileな人は「テストしろ! コード書け! リファクタリングしろ! 以下繰り返し!」とマントラのように繰り返す。でも、このやり方が設計を置き換える事はない。プロジェクトにおいて一連の作業が延々と繰り返されているだけなんだ。

Phil Hがこんな質問をしてきた:

新しいやり方ってのは、まずとにかくコードを書いて初期イタレーションの目的を達成し、それから必要に応じてリファクタリングを行い、洗練していくっていうことらしい。コードは漸増的に増えていく一方、全体的な設計はしていない。つまり、今まででいうところのソフトウェア設計という工程がリファクタリングに取込まれてしまった、ということか。きれいなコードは設計からでてくるはずで、漸増的に機能を追加していったらきれいなコードはでてこないはずだ。

上流設計(Big Design Up Front)は設計でもなんでもなく、設計を達成するための一工程に過ぎない。Agileな人達は、異なる手段をとろうとする。従来の設計では、開発されるべき機能を満たすにはどうすればいいかを考えていたわけでしょ。システムが必要としているものをどう実現するか考えるわけだけど、そもそもシステムが必要としているものが顧客の要求に応じて変化していくわけよ。

Agileのテスト駆動型なやり方では、システム設計は下記のように表現できる。

  • 新しく追加する機能のためのテストを書く
  • テストを実行し、失敗する事を確認する。実装しようとしている機能が未完成だから、失敗して当然だ。
  • テストに通るような最低限のコードを書く。
  • テストを実行し、ちゃんと通る事を確認する。
  • 新しく追加した機能を含めて、コードが洗練されるまでリファクタリングする。

要するに、このやり方だと「今」必要だとわかっている機能に専念して設計できる事になる。後から必要になる(かもしれない)機能で悩まされなくなるのだ。

Fabian SteegはKent Beckを引用してこう語っている:

目的はちゃんと動く、きれいなコードを書く事だ。(略) 最初に「ちゃんと動く」ことを実現する。それから、「きれいなコード」にする。これは古典的な設計駆動型とは反対のやり方だ。昔は「きれいなコード」ができるように設計がなされ、それから必死になって「ちゃんと動く」ように四苦八苦していたわけだから。

もちろん、文字通りに解釈し過ぎちゃう可能性はある。こんな書込みがあった:

設計を先に済ませてしまう理由は、そのほうが安くつくから。ある基盤に依存するコードを書いちゃうと、あとから他の基盤用に対応するのはとても高くつく。複数基盤に対応するよう、コーディング前に設計しておけば、安くあがる。

この人はAgile開発が事前に何も考えないと勘違いしている。設計においては、「今知っている」情報については考慮されるべきであろう。もし、将来複数基盤に対応するという事がわかっているのであれば、それを念頭において設計するまでの事だ。でも、単一基盤対応で当面は大丈夫だと自信が持てるのであれば、「いつの日か移植しなければならないかもしれない」などという可能性のために設計をややこしくする必要はないよね。

以下のAgileにおける考え方を参考にしてほしい:

あくまでも「考え方」だからね。この通りにやればうまくいく、なんて思わないでね。これらの考え方は、あくまでも開発者がどう考えればいいかの道筋を示すもので、開発者にこう考えろ、と指導しているわけではないんだから。