BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 立ち止まってリファクタリングをする?

立ち止まってリファクタリングをする?

原文(投稿日:2009/6/15)へのリンク

Joshua Kerievsky氏リファクタリングYahoo!グループにおけるディスカッションを次のポストから始めている。

ここ数年、リファクタリングを行うべきなのはユーザストーリーに関する作業を行っている時だけだという話を耳にしますが、その考え方にはまったく賛成できません。それというのも、単純に技術的負債を返済するべき時があると考えられるからです。この数日間、同僚と私はeラーニングのコードをリファクタリングしていますが、これを導くユーザストーリーはありません。想定した以上に技術的負債が増えてしまっていて、今はそれを返済するのにちょうど良い時期なのです。コードの中で中心的な役割を果たしているシングルトンが有害なものになっているので、それを取り除いています。それによって設計を改善する可能性がより広く開かれるからです。この作業は楽しいものです。これで、今後予定されているユーザストーリーの作業をするのが遥かに楽になるでしょう。

一方で、私たちは毎週リリースを行っており、そこでは若干の修正と多くのリファクタリングを行っています。いつものことですがマイクロテストとストーリーテストを自動化しているので、自信と勇気を持つことができています。

とにかく、興味深いディスカッションができそうだと思い、これを共有したいと考えました。

Dale Emery氏はKerievsky氏のコンテキストを明確に認識しようと試みた。

Emery氏 思うに、問題になっている一般的なアドバイスは、技術者がビジネスに関する決定を行ってしまうことを防ぐために存在しているのではないでしょうか。技術的負債を返済することを決定するには、ビジネスと技術両方に与えるインパクトに対するしっかりとした理解が必要です。意思決定をする人間が理解していなければ、その決定は信頼するに足らないものとなります。あなたが言っているのは、その危険性が低くなっている特別なケースです。

Kerievsky氏 そうですね、私たちのケースは特別です。それでも、ビジネス側の人々と技術者が密に連携しながら作業し、それによってこういった類いの技術的負債に関する意思決定が全員で共有されているのは、一般的にみて良いことだと言いたいのです。確かに開発者がリファクタリングに数週間を費やして、しかも実際にプロジェクト全体で共同した意思決定を一切行っていないというのは望ましいものではありません。

Emery氏 (もし間違っていたら直して頂きたいのですが)あなたの顧客は極めて技術に長けており、同時に技術者のうち全員ではないにせよ多くの人がビジネスについて詳細に理解しているように思えます。もっと言えば、あなたにとっての顧客はあなた自身です。あなたが技術的負債を返済すると決定する場合、ビジネスに関するインパクトについて完全に分かってやっているか、もしくは分かっているからこそやっているのです。

Kerievsky氏 その通りです。技術的負債をリファクタリングによって返済するという意思決定は次の点によって導かれています。

  • タイミング - ちょうど、最大の顧客に対する極めて重要なリリースが終わった所で、機能追加の手をしばし止める時期なのです。
  • 将来 - 更なる機能が追加される予定ですし、実際に今のコードで作業をしてみて、技術的負債によって生産性が下がることが分かっています。
  • ユビキタスランゲージ - コード内では素晴らしい音楽のメタファーを使っていますが、(中略)古い比喩(本)がまだコードの中に残っています。

こうしてKerievsky氏のコンテキストを理解した上で(この非常に長いスレッドを通じてより一層理解は深められているのだが)、Adam Sokra氏は次のように示唆している。

長さの決まったイテレーション("fixed iteration")で作業をしている訳ではないのですね。インクリメンタルに開発を行い、可能な限り頻繁にリリースをしていると。一連のユーザストーリーに関する作業を行っていて、それを顧客に対して素早くリリースしようとしていることもあれば、単により良いものにするためにデザインを改善しようとしていることもある。顧客であると同時にプログラマでもあるのですね。

これは私がこれまでに出会った、あらゆる優れたオープンソースプロジェクトと全く一緒であり、スクラムやXPのプロジェクトとはだいぶ異なっているように聞こえます。あなたがやっていることが何か問題があるとは決して思いませんが、アジャイルのコンテキストにおいてどうリファクタリングをするのかを理解しようとしている人々にとって本当に有効かどうかは疑わしいと思います。

スクラムとXPの中心的なコンセプトの一つは、技術的ではないビジネス側の人々の要求と技術チームの要求との駆け引きを行うことです。技術的な事柄が確実にうまく行われるようにしたいのですが、同時に、何が作られ、それがいつなのかということに関してビジネスが持つ影響力を最大化したいのです。

あなたが書いているのは、その二項対立が存在しない世界の話です。どんな機能を追加し、それをいつ追加し、またいつ機能提供の手を休めて純粋に技術的な問題についてフォーカスするのかを自由に決められるのです。

ここでSokra氏が示唆しているのは、Kerievsky氏のコンテキストが多くのプロジェクトには適用できないということだ。最も重要な違いは、コミュニケーションと理解と優先順位における技術的な観点と非技術的な観点との間のせめぎ合いが欠けている点にある。

Ron Jeffries氏は私たちが行うべきリファクタリングの量はビジネス上の決定であると示唆している。リファクタリングはその価値をすぐに得ることができない投資であるというのだ。またJeffries氏は「リファクタリングをしないこと」と「立ち止まってリファクタリングすること」という二分法に反対している。

ここには明確にされるべき前提があります。その前提というのは、とにかく、時に立ち止まるなり「前へ」進むのを緩めるなりして、コードをきれいにするのが良いことだというものです。

多くの人にとって、コードがあまりにも汚くなってしまい、できることと言えば機能追加を止めるか減らすかしてコードをきれいにすることだけ、という状況は明らかに起こり得るものであるようです。

これは私にとって自明ではありません。多数決が正しいということはないのです。コードをきれいにする場合、その作業の成果が得られるのは未来のいつかです。明日かもしれないし、数週間あるいは数ヶ月かかるかもしれない。しかし、今ではありません。

機能の追加を遅くするリファクタリングはすべて未来への投資です。明らかにしなければならないのは、その投資を行う価値があるのかどうか、それはいかにしてそうなのか、いつおこなうべきなのか、ということです。

Jeffries氏は続けて、リファクタリングはいつであれば実行する価値がある投資になるのかを決定するための方法を示唆している。

リファクタリングした方が良いのはいつで、それはなぜなのでしょうか?将来への道筋は数多く考えられ、機能的価値の成長については時間と共に明らかになります。この道筋について2つ取りあげます。

1. リファクタリングをしない。機能的価値が成長するペースはどんどんゆるやかになり、やがて横ばいになります。そしてもしかするとエラーの追加が機能の追加を上回るようになって、価値が減少し始めるかもしれません。

2. 機能追加の手を止めてリファクタリングを行う。機能的価値はしばらくの間「成長しません」。それが終われば、また成長を始めます。コードは前よりも良いものになっているので、成長速度は前よりも速いはずです。立ち止まっていなければ成長していたであろう場所に追いつくまでには少し時間がかかりますが、それを過ぎれば差がつき始めるはずです。

この2つだけを較べることで何を結論付けることができるでしょうか?1つめは、リファクタリングをしないことによって、リファクタリングが終わった後一定期間が経過するまでは、リファクタリングを行う場合「以上」の機能的価値を提供できるということです。2つめは、いつからリファクタリングの効果が現れるのかを知るためには、数字をいくつか把握しなければならないということです。すなわち、リファクタリングにどのくらいかかるのか。開発速度("velocity")に与える影響はどれほどか。コードが再び汚くなって、これらの数字が後退を始めるまでどのくらいかかるのか。

恐ろしいことに、立ち止まってリファクタリングを行い、機能を少々置き去りにして、新しい機能を閉め出し、追いつくどころかコードをめちゃめちゃにしてしまい、それが永遠に続いて利益がずっと得られない、ということはあり得ることです。残念ながら、もしメンバが十分なスキルを持っていなければ、これはあり得るのです。私が言いたいのは、あなたのアドバイスはエキスパートに対するものだということです。

しかしこれらの両極端は、この立ち止まってリファクタリングをするという戦略がそれ自体失敗する可能性があることを示しています。もっと良い方法は他に無いのでしょうか。あるのです。

ある種の「リファクタリング・アクセル(RA)」を想像してみて下さい。上に上げた1つ目のケースでは0.0、つまりリファクタリングなし、です。2つ目のケースでは1.0に設定します。つまり床まで踏み込んだ状態です。その中間では何が起こるのでしょう。

まず、RAの関数として見た場合、機能的価値に何が起こるでしょうか。0 < x < 1となる数字があって、そこでRA = xとすると、機能的価値の成長は常に遅くなります。十分なリファクタリングをしなければコードは劣化し、どんどん事態が悪化します。RA = xとしておけば、機能的価値は一定の割合で成長します。スピードアップすることもスローダウンすることもありません。その時の開発速度がどうあれ、それを保つことができます。

さて、リファクタリング・アクセルがxより大きかったらどうなるでしょうか。つまり、RA > xの場合です。さらに速くなるのか、あるいは常に遅くなるのか。1つ分かっているのは、RA = 1.0の場合です。その時にはゼロになるまでスローダウンします。(後でスピードアップすることができるのですが。)

この問いに対する答えは、コードのきれいさに対応する開発速度の曲線の種類によって変わってきます。周知の通り、極めてきれいなコードは高い開発速度に結びつき、また周知の通り(だと思うのですが)、コードをきれいにする作業は早くやればやるほど高い効果が生み出され、最後に磨いたものはたいしたものをもたらしません。

私が強く信じているのは(それが違うという証拠はまったくないのですが)RAをxの少し上に押し上げることによって機能追加をより一層速めることができるということです。もしこれが事実であれば、この戦略はリファクタリングのために立ち止まる戦略よりも一貫して速いスピードで価値をもたらすことになります。

したがってもしこれが事実なら、そして私はこれが事実だと確信しているのですが、リファクタリングのために立ち止まる戦略はリファクタリングをするのに十分なスキルを持ったチームにとってベストなものとはなり得ないのです。

Jeffries氏がここで主張しているキーポイントは、「立ち止まってリファクタリングをする」戦略がリファクタリングに長けたチームにとっては「断じて」最善の選択ではないということだ。

この長いレポートはこれでも、極めて魅力的なディスカッションのごく一部にすぎない。Kerievsky氏がディスカッションの最初に説明している通り、これは新しく生まれた疑問ではない。実際著者はリファクタリングは必要な無駄と題した論説を2年前に書いているし、InfoQがカバーしたリファクタリングのトピックも幾度となく繰り返されている。コミュニティはこのトピックに関してまだコンセンサスに達していないのだ。

この記事に星をつける

おすすめ度
スタイル

BT