mtx2s’s blog

エンジニアリングをエンジニアリングする。

コード品質はやはりビジネスに影響を与える

私たちソフトウェアエンジニアは、コード品質についてしばしば論ずるけれども、ではコード品質の良し悪しがどれほどビジネスに影響するのかと問われると、回答に窮する。只々、「コード品質が悪いと変更により多くの時間がかかります」だとか、「欠陥の修正に追われて開発時間が奪われます」だとか、個人の経験やエンジニア的一般論に頼った定性的な説明に終始するしかない。ソフトウェアを繰り返し変更する頻度が高いほど、コード品質が開発時間に影響を与えるのは確かにそのとおりだと思えるが、はたしてそれは、どれほどのインパクトなのだろうか。

2022年の研究論文 "Code Red: The Business Impact of Code Quality – A Quantitative Study of 39 Proprietary Production Codebases" では、コード品質がビジネスに与えるインパクトを「時間」という形で計測している。市場投入までの時間というものが、ビジネス上での競争優位を左右するという考えからだ。

本稿では、前述の論文を中心に、「市場投入までの時間」という観点で、コード品質とビジネスの関係について考える。

市場投入までの時間とコード品質の関係性

「市場投入までの時間というものが、ビジネス上での競争優位を左右する」とは言うが、「市場投入までの時間」と「コード品質」との間には、どのような関係が存在するのだろうか。

マーク・リチャーズ(Mark Richards)らの著書『ソフトウェアアーキテクチャの基礎』では、「市場投入までの時間」を関心事とした時に必要となるアーキテクチャ特性のひとつに「アジリティ(agility)」を挙げている。同書では、ソフトウェア開発におけるアジリティを「変更に迅速に対応する能力」としている。

また、和田卓人による『アジリティを支える品質特性』によれば、アジリティと関係の深い品質特性は「保守性(maintainability)」であり、その品質副特性として「理解容易性(understandability)」「変更容易性(modifiability)」「テスト容易性(testability)」を挙げている。これは、バリー・ベーム(Barry Boehm)らによる保守性の定義によるものだ。

そしてこの保守性とは、コード品質がもたらすものであることから、コード品質が「市場投入までの時間」を決定づける要因であることが分かる。

市場投入までの時間を短縮するには、アジリティと並んで「デプロイ容易性(deployability)」も忘れてはならない。ビジネス上のパフォーマンスを高める上で、テスト容易性と並んでデプロイ容易性が重要である点は、書籍『LeanとDevOpsの科学』でも述べられているところだ。これらのアーキテクチャ特性を高めるためには、疎結合アーキテクチャが求められるという点でコード品質とも関係する特性であると認識すべきだろう。

計測結果とリポジトリマイニング

"Code Red: The Business Impact of Code Quality – A Quantitative Study of 39 Proprietary Production Codebases" では、次の3つの結果を得ている。なかなかの衝撃的な数字だ。

  1. 低品質なコードに含まれる欠陥は、高品質なコードの15倍
  2. 低品質なコードの平均開発時間は、高品質なコードの2倍
  3. 低品質なコードの最大開発時間は、高品質なコードの9倍

具体的な測定結果は、論文内に掲載された次の表のとおりだ。

ここでのコード品質の判定は、コード分析ツールのCodeSceneによって計測されるCode Healthというメトリクスが使われている。このメトリクスは、コード品質を、最も低品質であることを示す1.0から最も高品質である10.0までの数値で表す。これを更に、10.0から8.0の間であれば "Healthy" とし, 8.0から4.0を "Warning", 4.0から1.0を "Alert" として、コードベース内のそれぞれのファイルを3つのカテゴリのいずれかに分類している。上記の「低品質なコード」とは "Alert" とされたファイルであり、「高品質なコード」とは "Healthy" とされたファイルを指す。

開発時間(Time-in-Development)の計測は、JiraとGitのログから得ている。例えば、コミット#1がJiraの課題Xと紐付けられていたら、そのコミットで変更されたファイル1の開発時間は、課題のステータスが "In Progress" となってからコミットされるまでの経過時間となる。次のコミット#2が、同じく課題Xと紐付けられ、ファイル2を変更していた場合、ファイル2の開発時間は、コミット#1からコミット#2までの経過時間となる。さらに、課題Xに紐づくコミット#3がファイル1とファイル2の両方を変更していたら、ファイル1はコミット#1での計測時間に、コミット#2からコミット#3までの経過時間が加えられる。ファイル2も同様に、コミット#2での計測時間に、コミット#2からコミット#3までの経過時間が加えられる。また、課題タイプが「バグ」であるかどうかも見ている。

このようなリポジトリマイニングの対象とされたコードベースの数は、論文タイトルにもあるとおり、39である。

「欠陥が15倍」による影響

欠陥が多いということは、予定外の作業がそれだけ増えるということだ。Jiraで「バグ」に分類された課題の平均数が、"Healthy" と判定されたファイルと "Alert" と判定されたファイルで15倍も違うなら、コード品質の良し悪しは見積り精度に影響を与える

バグ対応に要する時間は、開発計画にどれだけ組み込まれているだろうか。おそらく「バッファ」という形で吸収できるよう、計画に組み込まれているプロジェクトも多いと思うが、あまりにバグが多すぎてバッファを消費しきってしまうことだってあり得る。そのようなプロジェクトは、市場投入を計画通りに進められず、遅延を起こす。それが、ビジネスに悪影響を及ぼす。

さらに、顕在化されたバグがそれだけ多いということは、潜在的なバグが多いであろうことも予想できる。そういったバグが市場投入後に障害を起こす。そうして、開発者は障害対応に追われ、開発時間を失っていく。それが進行中のプロジェクトの計画にも悪影響を及ぼし、遅延に遅延を重ねる結果となる

「開発時間が平均2倍、最大9倍」による影響

品質が悪ければ、開発時間がより長くなるという傾向が、計測結果によって明らかにされた。"Healthy" とされたファイルと "Alert" とされたファイルを比較した場合に、平均開発時間では後者は前者の2倍以上、最大開発時間では9倍近くとなった。

この結果は、単に開発時間が長くなるといういうだけの問題ではない。「見積り」という観点で、予測可能性が著しく下がることも意味する。算出した見積りに対し、結果として、2倍から9倍もの時間がかかってしまうかもしれないということだ。カテゴリごとに見てみると、"Healthy" では平均開発時間に対して最大開発時間が2倍弱、"Alert" だと7倍以上に達する。コード品質が悪いと、開発時間が長くなるだけでなく、ファイルごとの開発時間のばらつきも大きくなるということだろう。

このように、コード品質の良し悪しが、市場投入までの時間を引き伸ばしてしまうだけでなく、計画に対する予測可能性を損なわせる要因になっているのだ。

「予測可能性の低下」という問題

先述した3つの計測結果はまさに、「市場投入までの時間」という関心事に対し、コード品質が影響することを示した。コード品質が低ければ、開発時間をより必要とし、さらに予測可能性の低下がプロジェクトの計画を瓦解させる。そしてこれらは結果として、ビジネスの機会費用や機会損失につながる。

このような状況に陥った開発チームは、見積もり時にバッファを可能な限り大きく積むことで、なるべく確実性の高い市場投入日を計画するようになる。しかし、これでは市場投入までの時間がむやみに引きのばされただけだ。こんなやり方は、プロジェクト関係者の不信感を生む

根本的には、すでに劣悪になってしまった既存コードの品質を改善しなければならない。しかし、コード品質が十分に高くなるまでプロジェクトを不安定な状態で放置するわけにもいかない。プロジェクトの予測可能性を高めるための計画づくりが必要だ。

スクラム開発のようなアジャイル開発手法であれば、それはイテレーションごとにチームのベロシティを見直すことで実現できるかもしれない。直近の数イテレーションでの見積り予実を比較することで、1回のイテレーションでどれぐらいの開発が進められるかを補正できる。これなら、予測可能性を高められる。それに、このようにチームの実績統計に基づいて算出された見積りであれば、プロジェクト関係者も納得するだろう。

これは、「コード品質が悪化すると、チームのベロシティが下がる」という前提に基づいている。ベロシティが下がる要因は、ここまでで見てきた通り、予定外の作業が発生しやすくなることと、1つの変更に対する開発時間が長くなることだ。

しかし、見積りをストーリーポイントで行っているなら注意点がある。コード品質が良い状態でチームが完了したイテレーションのストーリーポイント合計が100ポイントだったとしよう。ベロシティは100となる。では、これとまったく同じ内容の開発を、コード品質が悪い状態で見積もったらどうなるだろうか。100ポイントのままだろうか。100ポイントより大きくなるだろうか。いずれにしても、1回のイテレーションには収まりきらないだろう。したがって、前者の場合はベロシティが下がる。しかし、後者の場合はベロシティが下がらない

もう少し詳しく説明すると、チームはベロシティを100としているので、前者では例えばイテレーション完了時点で100ポイントのうちの67ポイント分だけが完了して、ベロシティが下がる結果になる。しかし後者の場合、見積り時点で150ポイントといった数字になるので、今回のイテレーションでは150ポイントのうちの100ポイントだけを計画に含めることになるだろう。したがって、ベロシティは100のままだ。

どちらの見積り方法が正しいかは知らないが、前者はコード品質の悪化がベロシティに現れ、後者はコード品質の悪化が見積りに現れる。定点観測するなら、前者の方が時系列での変化を追いかけやすい。後者は、何を比較すれば良いのかわからない。それはすなわち、コード品質の悪化を関係者に説明することが難しくなることを意味するのではないだろうか。

ただ実際のところ、コード品質が悪ければ「予定外の作業」が増えるので、どちらの見積り方法であっても結局はベロシティは下がるだろう。それならば、あまり気にする必要はないのかもしれない。ただ、「予定外の作業」も「1つの変更に対する開発時間が長くなること」も、どちらの影響もベロシティに現れた方がシンプルではないかとも思う。

コード品質を誰の目にも明らかにする

Googleが言うように、ソフトウェアエンジニアリングは、たった1度書いて終わりのプログラミングとは違う。「ソフトウェアエンジニアリングとは時間で積分したプログラミングである」という言葉が示すように、何度も繰り返し変更されるソフトウェアを対象としている。そして、少なくともその活動が人間の営みである間は、保守性を高め、維持し続けることだけが、コードベースに変更を繰り返すことを持続可能にする。「ソフトウェアを保守性のある状態に長期間保つということは、不断の闘いにほかならない」ということだ。

Stripe社のレポートによれば、開発者の平均的な1週間の仕事時間41.1時間のうち、42%にあたる17.3時間は、品質の低いコードによって無駄に費やされている。また別の調査では、技術的負債の管理に費やされる開発時間は開発全体の25%であるが、その追跡にツールを利用する組織はわずか26%で、体系的に追跡している組織は7.2%しかなかった。バックログや、静的コード解析ツールなどが活用されていないということだろう。

一方で、コード品質の問題を認識しているのは、開発者やアーキテクト、プログラムマネージャーであり、経営者やビジネスマネージャーはほとんど認識していない(42%)という調査結果もある。そして、コード品質の問題を積極的に管理していると解答したビジネスマネージャーは、わずか10%しかいなかった。

これらの結果からも分かるように、やはり、コード品質の問題が組織の中で可視化されず、エンジニアしか認識できない状態に置かれているのだ。これでは組織としてコード品質の問題に取り組むことなどできるはずもない。だから、コード品質との闘いは、エンジニアだけの活動になるのだ。しかし、ツールを活用してコード品質を積極的に可視化し、追跡可能にできれば、組織内で問題・課題を共有できる。数多くある静的コード解析ツールの中には、コードの問題を特定したり、メトリクス化するだけでなく、その問題を解消するために要するであろう工数の参考値を出してくれるようなものもある(経験的に言って、それらの精度に期待しすぎることはできないのだが)。

考えてみれば、プロジェクトやプロダクトの定期報告には、売上やコストといったビジネスメトリクスや、アクティブユーザー数やダウンロード数といったユーザー行動に関するメトリクスは含まれても、コード品質に関する情報は含まれない。報告に含まれるのは、せいぜい、障害発生数や欠陥数ぐらいだろう。コード品質の問題が積もり積もって大きくなり過ぎた時にはじめて、その解消に時間が欲しいとエンジニアが相談を切り出す。これではコミュニケーションが上手くいくはずもない。私たちエンジニアは、こういったコミュニケーションにも、もう少し目を向けるべきではないだろうか。