レガシーコードには作り直し? リファクタリング?
レガシーコードには作り直し? リファクタリング?
昔に比べると開発が終わったらあとは保守のようなものは減り、常に開発し続けていることが増えたように思います。毎年規模が大きくなり、複雑化していき、修正がどんどん手に負えなくなります。
手に負えなくなったときに作り直したらいいかリファクタリングをしたらいいかというのは悩みどころだと思います。
作り直し V.S. リファクタリング
結論から先に。作り直してもリファクタリングをしてもうまくいかないことが多いです。
複雑になったレガシーコードは修正が怖いという感覚があります。しかし、この状態は何が問題で修正が難しいのかが論理的にわかってません。ということはこの問題が解決された状態も知らないことになります。
作り直しでもリファクタリングでも、問題を認識してそれが解決された状態に近づけることは変わりません。問題を論理的に分析できていない状態では、どちらをとってもうまくいきません。
作り直しても度重なる修正で数年もすれば元に戻るでしょう。リファクタリングでも、意味のない関数への抽出などで、かえって読みづらくなり修正が困難になります。どちらがいいかっていうより、どちらがよりましかというレベルです。
どうすればいいの?
どちらを選ぶかの前に、現状何が問題になっていてどのようにすれば解決するのかを論理的かつ感覚的に開発チームが理解する必要があります。この力を開発チームが身につければ、どちらがいいかは開発チームが自発的に決められるようになります。
とはいえ、開発チームがこれらを学習するのは膨大な時間がかかります。そこまで結論を先延ばしにすることは商業的にはありえません。ですので、学習を続けつつ、少しずつ今のコードをリファクタリングしながら、部分的には作り直し、様々な経験を積むことが一番です。
作り直しをする V.S. リファクタリングをするではなく、古いのはそのままでも構わないので、新しく書くところは以前のやり方をすべて捨てて新しい方法を導入し、試行錯誤をします。これをするために、新旧混在で動作するフレームワークづくりが重要になります。
古いコードでリファクタリングできるところはリファクタリングし、新しいコードでそれを再利用するのも欠かせません。レガシーコードは往々にして 1,000 行の関数のうち 20 行くらいは新しいコードでそれを再利用したいということがありますが、20 行くらいを関数に抽出できるなら、それを新しいコードでも再利用できます。この抽出したい 20 行のコードは、ちょうどいい手続きの塊です。最初から関数に分かれていればよかったはずです。このような体験をたくさんすると、いい関数とはどういうものかが分かるようになってきます。関数に分かれていたらよくなるという考えではなく、具体的にこんな感じで関数に分かれていると色々とやりやすくなるんだという気付くことが大切で、何度かこれを体験すると、新しいコードでもいい関数を書くようになります。
このような試行錯誤のために、テスト駆動開発が重要になります。テストコードを書いたら良くなるとは考えないようにしてください。テスト駆動開発は、テストを高速で回すことで試行錯誤の回数を二桁とか三桁とか増やすことができます。人が能力を身に着けるには試行錯誤がとても大切です。テストコードは試行錯誤のための開発者の武器です。
技術だけじゃない
ここまではどちらかというと技術よりのお話でしたし、それもレガシー化していく大きな要因なのは間違いありません。もう一つ、開発チームの能力を超えた仕事を投入しているという大きな問題があります。いわゆる締め切り駆動開発です。こちらも必ず解決する必要があります。
(余裕がないのにも関わらず、誰も使われなさそうな機能追加をするとかもやばいです)
この状態では、作り直しもリファクタリングも時間に追われます。結果、たいして良くならないでしょう。しかし、良くなったと全員が認識して、じゃあこれから仕様変更をじゃんじゃんやっていいよね! あれもこれもやりたい! となりがちです。
一般的に、保守性の高い設計ができるようになると、複雑化を抑えられ、修正に対するコストを下げられます。しかし、このような開発チームの能力を超えた仕事を投入している場合、テストを締め切りが近いからとなんとなくのカンでさぼっており、保守性の高い設計のメリットのテスト工数の削減の恩恵があまりありません。
開発チームの能力を正しく計測できていない状態では、技術的な解決策の利点を大きく損ないます。おそらく技術的な問題よりも一朝一夕で解決はできませんので、解決を模索し続ける必要があります。
余談ですが、開発手法のスクラムは、この開発チームの能力の計測に関して、かなり工夫されているなあと感じます。(スクラムをすべきとか、スクラムをしたらよくなると言っているわけではありません)
最後に
作り直し V.S. リファクタリングは正直どうでもいい議論です。問題を正しく認識し、その解決ができればどちらでも構いません。そのために必要なことは方法を決めることではなく、試行錯誤や体験、書籍やコンサルなどから様々なノウハウを学習し続け、作り直しとリファクタリングを組み合わせることです。
今のコードが複雑で修正をしたくないと感じるなら、それは技術的にも非技術的にも問題があります。これらの解決は一朝一夕ではできません。短期間に一気に何とかして後は何もしないのではなく、解決の方法を模索・試行錯誤し続けることが大事です。
追記
書くの忘れてたけど、レガシーはコードの方よりデータベースがしんどいです。レガシーなデータベースはコードの足を引っ張るんですよね...
Discussion