リファクタリングの価値を概算する

元ネタは、以下にあるリスクの計量です。

https://twitter.com/moonmile/status/1683420756598988800

リファクタリングの価値の考察 – プログラマーの脳みそ https://nagise.hatenablog.jp/entry/2022/08/12/121524

ここにある需要と供給の交点「均衡点」をどのように算出するのか?という話…だと思うのですが、要は、「開発者がリファクタリングしたいと言ったとき、プロジェクトマネージャや顧客をどのように背って説得するのか?」と言う問題です。

開発者にとっては、リファクタリングは価値があるものとして当然な結果なのですが、マネージャーや顧客にとっては「価値がない」ものとして認識されがちです。

  • リファクタリングの間は、進捗が上がらない
  • リファクタリングすると、コードが減る(進捗が悪くなる)
  • リファクタリングをして、コードが良くなったというが、いまのままでよいのではないか?
  • リファクタリングをして、将来の保守性を上げるというが、どれだけの効果があるのか?今のままでよいのではないか?

という返答を貰いがちです。

結果、リファクタリングをするための正式な時間(プロジェクトとして計上される時間)が取れずに、

  • 開発者の個人的な時間を使って、リファクタリングする
  • 開発者が何らかの進捗を上げた後で、隙間時間でリファクタリングする

ということに陥りがちです。これは隠れたコストであり、隠れたリスクでもあります。

リファクタリングに限らず、コードを綺麗に書くことなどの価値は算出できない≒不確実性が多い、というのでそのままになりがちなのですが、ここは「マネージャーや顧客にも責任を担保してもらう」という意味でも、リファクタリング価値を説明可能なものにしておくのがベターでしょう。

という提案ですね。

リファクタリング自身の価値を正確に計測するのが目的ではなく、リファクタリングの価値を可能なものにする(ときには、今回のリファクタリングは諦めたほうがよい)のが最終的な目的です。

リファクタリングの工数が、リスクを上回るとは?

損益分岐点として、以下を想定します。

リファクタリングの工数 < リスクや保守の発生時の費用

ここは異論はないと思います。リファクタリング自身には実際に手を動かすことになるので工数が掛かります。また、未来においては、保守や変更、リスクが発生したときの対処などなどの「費用」が掛かるのは確かです。

この「費用」をマネージャは顧客に説明しやすいように厳密にします。

  • 開発プロジェクトが完了した後に、なんらかの保守作業(画面の変更など)が発生します。
  • 開発プロジェクトが完了した後に、なんらかの外部的要因(法改正など)で変更作業が発生します。
  • 開発プロジェクトが完了した後に、高パフォーマンス要求(ユーザー数の増加など)で性能をアップさせる必要があります。

ここで注意しておきたいのは、開発プロジェクトの瑕疵によりコードを修正する必要がある、というような開発者都合ではないものにしておきます。実際、リファクタリングで重要なのは、不具合を減らすためでもあるのですが、ここではマネージャーや顧客に説明し易いように「開発プロジェクトは瑕疵なく完了している」という状態にしておき、そのあとの追加部分だけを対象にします(それが不可能であっても、可能であると想定します)。

開発プロジェクトは無事終了し、納品が終わっているのですが、DevOps 的に言えば運用保守の段階です。ここで、まったく変更がなければ=売り切りであるのであれば、追加費用としてはゼロです。ゼロの場合には、リファクタリングの余地はありません。開発プロジェクト内の問題としてリファクタリングの工数を捻出しないといけないので、ここでの論法は使えません。諦めてください(とはいえ、開発段階でのリファクタリングは必須であるので、別の方法は後述します)。

開発が終了して、運用保守段階には行った後に、なんらかの追加や変更が発生します。これは、無料で行うのではなくて、なんらかの「費用」が発生します、と定義します。

変更費用を見積もる

そうなると、式を少し書き換えられます。

リファクタリングの工数 < 追加変更数 × 人月単価

「追加変更数」というのは、画面の変更や文言の変更、機能の追加なんどの諸々の数です。正確には sum を使うところですが、ここではざっくりと「追加変更数」でいいです。

変更数は生来的なものであるので、確定的なものではありません。先に書いたように、変更数はゼロかもしれないし、あるいは100かもしれない。バラツキがあり確率的なものです。ここでいう「確率」というのは、プロジェクトが完了して運用に入ったときに、なんらかの変更点(顧客由来の)が加わったときに、どのくらいの確率で変更が発生するのか?ということです。確率は分布します。年間0個かもしれないし、100個かもしれません。インシデントという形で年間10個までという決め方もできる、年間保守費用の中に入っているかもしれません。これは、未来のことなので確定的なものではありません。

確定的ではないのですが、おおまかに予想します。保険会社のように統計的に算出する必要はありません。概算で大丈夫です。概算自体は、開発プロジェクト側ではなくて顧客側が「予算」としてやってくれるものです。

さて、運用されているシステムが、何年使われるかわかりませんが(これも、1年、10年、100年で概算してもよいです)、年間12個の変更点を許容すると考えましょう。だいたい、月1に何かを修正するという考え方です。定額の保守費用を考えるときも、顧客の懐具合を見ながら予算を立てます。また、保守費用を大きく上回る場合は追加費用を貰うのが普通と考えらえます。あくまで見積もりのうちなので。

では、1個の修正に関してどのくらいの予算を掛けるのかを考えます。端的に言えば、どのくらいの人月が掛かるか?ということです。

計算を単純にするために、1個の追加に対して2週間(0.5人月)かかると考えましょう。2人プロジェクトであれば1週間、5人プロジェクトであれば2,3日という具合です。「人月の神話」に反していますが、顧客に対しては人月のほうが通りが良いので、この計算のほうが楽です。

単価を100万円と考えます(多いか少ないかは別として、計算上なので)。

そうすると、年間の変更が12個と予想され(実際に12個あるかどうかは別として、将来的な予想です、1個の変更に対して 0.5人月を見積もり、単価が100万円なのですから、

年間の変更費用 = 12 x 0.5 x 100万円 = 600万円

です。凄い金額ですね。これが、運用5年とかになったら、3000万円とかになって開発費用を大きく上回るかもしれません。

リファクタリングの費用を見積もる

さて、年間の変更費用が 600 万円と仮定しました。そんなに掛かる訳ないだろうという意見もあれば、そんなに掛けられないというのも当然です。

最初の式である、

リファクタリングの工数 < リスクや保守の発生時の費用

に立ちかえれば、リファクタリングの工数が、この 600万円(年間であれば)を下回ればよいのです。

単価100万円という計算をしたので、リファクタリングの工数は

6人月 x 100万円

のように求められます。この場合、リファクタリングによって、年間12個の変更費用がゼロ円になってしまうので、もうちょっと変更が必要です。

リファクタリングをすると、変更時のコストが安くなる(開発者にとって変更が楽になる)という式に変えてみましょう。

リファクタリングありの変更費用 + リファクタリング代金 < リファクタリング無しの変更費用

となればよいので、

リファクタリング代金 < リファクタリング無しの変更費用 – リファクタリングありの変更費用

となるので、リファクタリングの代金は、変更費用分の差額になります。

つまり、後の変更費用(未来の変更費用)が安くなるように、リファクタリング代金を決めればよい訳です。開発者視点としてはここをイコールで結んでもいいのですが、マネージャーや顧客視点として、リファクタリング代金のほうがより低い、という想定にします。

まず、これがリファクタリングをする意味です。このリファクタリングの代金が、変更費用の差分よりも高いのであれば、顧客視点からみてリファクタリングをする意味がありません。

リファクタリングに利用できる時間を算出

リファクタリング費用の最大値が求まったので、これを時間に直します。

リファクタリング費用 = リファクタリング日数 x 開発単価

ここでも計算が簡単になるように人月計算します。開発者の単価(人数や単価)にリファクタリングに掛ける日数を掛ければ、リファクタリングの費用になります。先に、リファクタリング費用の上限を決めたので、この「リファクタリング日数」が、開発時にリファクタリングとして利用できる時間になります。

実際のところは、リファクタリングによって開発効率が上がるという開発期間自体の効果もあるのですが、ここでは開発後の保守費用に対して焦点をあてています。これは、開発時に「何故リファクタリングが必要なのか?」を損益分岐点という形で、マネージャや顧客に説明するための資料として使うためです。

私的な問題でもありますが、個人的に目の前のコードをリファクタリングすべきかどうか(特に、誰かからの引継ぎの場合)にも同じ視点を使います。

  • 開発の効率化の差によっては、リファクタリングをしない
  • 保守性の差によっては、リファクタリングをしない

という選択肢を用意しておきます。多少設計がぐちゃぐちゃであったとしても、今後変更が全くないのであれば、リファクタリングで設計を綺麗にするよりも、コードがきちんと動くことを優先させる、という意味あいです。

逆に、何かリファクタリングっぽいもにのを始めたときに、実際「このリファクタリングが効果的かどうか?」の算出にも使います。開発時間は有限なので、いつまでもテストコードやリファクタリングをしてる訳にはいきません。なんらかの上限が必要になるのです。

最初からリファクタリングの時間を見込む

ここまでの話は、既に開発プロジェクトがスタートしてしまった開発途中にリファクタリングが発生したときを想定しています。ですが、どのプロジェクトもリファクタリングのような作業が発生するのであれば、プロジェクトを計画したときに「リファクタリング時間」を見込んでおいたほうがいいですよね。そのほうが、プロジェクト全体の費用も通しやすくなります。

顧客への説明としては、リファクタリング時間として次のように項目を用意します。

  • IBMが推奨する「ソフトウェアインスペクション」の時間を設ける
  • コード品質を確保するために「ピアレビュー」を定期的に行う
  • スクラムスプリントで最終の金曜日はリファクタリングの時間とする
  • ウォーターフォール方式で、品質確保のため設計見直し、コード見直しの期間を設ける
  • チケット駆動で、リファクタリングのチケットをあらかじめ作っておく

リファクタリングという単語を使っていますが、要は品質管理の一環です。ISO9000 の品質チェックあるは是正処置のひとつでもあるし、「プロジェクト・シン・エヴァンゲリオン」の中にあるリテイクに対するトリアージという仕組みと同じです。リテイクのトリアージのほうは、別途まとめておく予定です。

カテゴリー: 開発 パーマリンク