リファクタリングやリライトの目的は、コードの可読性、構造、明確さを改善することでシステムの健全さを改善する点にある。クリーンなコードはメンテナンスもエンハンスも楽だろう。しかし、多くの状況下にて、アジャイルチームはリファクタリングとリライトのどちらを行うかで厳しい選択を迫られる。
Michael Dubakov氏は、コードベースが時と共に劣化する理由として、以下のものを示している。
- 次々と増加する機能 これにより複雑さが増加します。
- 近道とハック これは「この手の込んだ検索が8月までに必要なんだ。以上!」的な機能をサポートするために行われます。
- 開発者のローテーション 新しい開発者はアーキテクチャの背後にある本質的な決定とアイデアを、全て知っている訳ではありません。変化に合わせて知識が失われていくのは避けられないのです。
- 開発チームの拡大 人が増えると、コミュニケーションが減ります。コミュニケーションが減ると、悪い決定がなされます。
Dubakov氏によれば、リファクタリングとリライトをすることでよりクリーンなコードにたどり着くけれども、どちらのテクニックも既存のシステムにカオスをもたらす。リファクタリングは少しずつ行う活動なので、一度にシステムのある部分だけに触れることになる。これは局所的に見ればカオスを生み出すのであり、またカオスを含みやすいとも言えるだろう。一方で、リライトはより侵略的な変更であり、システムにより大きなカオスをもたらす。インパクトはより広範囲にわたるので、リライトが安定するまでにかかる期間("stabilization period")はリファクタリングよりもはるかに長くかかる。
リライトの間も古いシステムは残っているので、カオスが絶えず存在することになります。公のリリースの後では、カオスは無視できないほど増加します。多くの新しいバグや不具合(と古いバグや不具合)が想定されますので、安定するまでにかかる期間は長くなります。
Peter Schuh氏はしばしば複数のチームが異なる単語を置き換え可能なものとして使用し、それがさらなる混乱とカオスを生み出す結果になると言う。リライトがリファクタリングに比べてリスクの高い提案であることをチームは理解すべきであり、したがって用語法もそれに従って用いられなければならないのだ。氏はこう語っている。
これは意味論にすぎません。そう、誰かが傷つくまでは意味論にすぎないのです。コードをリライトすることにはリスクが伴いますし、時として苦痛を伴う努力です。常にうまくいく訳ではありません。もし私たちがリライトを行いつつそれをリファクタリングと呼び、全てが失敗に終わったら、ビジネス側の人は誰も立ち止まって意味論について考えたりはしないでしょう。次にリファクタリングという単語を聞いた時に縮み上がるだけなのです。
Guido A.J. Stevens氏は興味深い観察をしている。氏によれば、問題はリファクタリングとリライトの間にあるのではない。問題はリファクタリングだけをするか、リファクタリングとリライトを両方するかにあるのだ。チームがシステムをリライトすると決定した時でさえ、最終的には2つのシステムが平行して走ることになる。古いシステムにはリファクタリングが必要だろうし、新しいシステムはリライトされることになる。この2つの組み合わせはあまりに複雑なタスクだ。氏の言葉を引用する。
衰え行くコードベースをメンテナンスしつつ、なおかつ新しいシステムを書くことは、リソースを枯渇させることになるでしょう。あなたのチームは分断され、遅延が発生することになります。計画をしっかり立て、注意深く移行をしなければなりません。その一方で、あなたの競合企業は製品化に時間がかかるという問題を抱えておらず、あなたの顧客を奪おうとするでしょう。しかし、あなたがもしこの現実を見据えた上で、なおリライトに賭けようと思うのであれば、成功のチャンスがあるかもしれません。
Naresh Jain氏は、特にレガシーコードに関して次のように提案している。コードが難解で、それが何をしているのかチームでも良く分からないのであればリファクタリングせよ。コードが何をしているのかが明確でありながら、理解するのが難しければリライトせよ。
このように、リファクタリングの方が少しずつシステムを改善するのには好まれる。ペースは遅く、小さく継続的な改善によって品質を高める。リライトにはメリットもあるが、多くの状況ではよりリスクの高い選択肢であり、チームはその結果を確実なものにすることはできない。Joel on Softwareに、次のようにある通りである。
次のことを覚えておくことは重要です。あなたがスクラッチから始める時、最初の時よりも良い仕事ができると信じるに足る理由は一切ないのです。