mtx2s’s blog

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

マイクロソフトの調査にみるコードのオーナーシップと品質の関係

ひとつのソフトウェアコンポーネントが多くの開発者によって変更されると、品質に悪い影響を与えると経験的に感じている。設計に一貫性が失われることや、知識の浅い状態で変更することによるバグ混入の可能性が高まるからだ。

2011年9月に公開されたマイクロソフト社の調査結果、"Don’t Touch My Code! Examining the Effects of Ownership on Software Quality" は、この「コードのオーナーシップはソフトウェアの品質を左右する」という経験則を裏付けるものだった。全体のコミット数のうち5%未満の貢献にとどまる開発者が多いコンポーネントは、リリース前後における故障が増加するというものだ。

本稿では、このマイクロソフトによる調査結果を紹介し、それを踏まえた上で、ソフトウェアプロダクトの品質悪化を抑えるための組織やプロセス、アーキテクチャについて簡単に考えてみる。

用語:コンポーネントのコントリビューターとオーナーシップ

さきに用語についてであるが、特に重要なものは次の4つだ。

  • コントリビューター(Contributor)
  • オーナーシップ率(Proportion of Ownership)
  • メジャーコントリビューター(Major Contributor)
  • マイナーコントリビューター(Minor Contributor)

この調査では、コンポーネントを変更/コミットした人を、そのコンポーネントに対する「コントリビューター」と呼んでいる。

コンポーネントXに対するコントリビューターAのコミット数が、X全体のコミット数の何パーセントにあたるかを表すメトリクスは、「オーナーシップ率」あるいは単に「オーナーシップ(ownership)」と呼ぶ。

オーナーシップが5%以上のコントリビューターを特に「メジャーコントリビューター」と呼び、5%未満では「マイナーコントリビューター」と呼んで区別している。

結果:マイナーコントリビューター数が故障数に大きな影響を与える

調査では、Windows VistaWindows 7という、2つの大規模ソフトウェアプロジェクトを対象としている。下の表は、それらのリリース前後の故障と各メトリクスとの相関分析結果となる。表内の数値が相関係数で、1に近いほど両者の間に強い正の相関があり、一方が大きくなると、もう一方も大きくなる関係を表す。また、-1に近いほど強い負の相関があり、一方が大きくなると、もう一方は小さくなる。

Ownership Metrics に分類されている TOTAL, MINOR, MAJOR, OWNERSHIP はそれぞれ、コントリビューター数、マイナーコントリビューター数、メジャーコントリビューター数、オーナーシップのことだ。OWNERSHIP には、それぞれのコンポーネントの最大コミット数を持つコントリビューターのオーナーシップが使われている。Classic Metrics に分類されている Size, Churn, Complexity は、静的コード解析でおなじみのコード品質に関するメトリクスだ。

Windows Vistaの結果を見ると、Ownership Metrics のうち、MAJOR を除いたいずれのメトリクスも、リリース前後の故障と強い相関関係がある。トータルのコントリビューター数やマイナーコントリビューター数が多いコンポーネントは故障が多く、オーナーシップが高いコンポーネントは故障が少ない傾向が強い。これは、概ね期待通りの結果だろう。Windows 7のリリース前も同様の傾向だ(リリース後の相関係数が小さくなっているのは、この時点ではリリース後の故障に関する報告が集まってなかったからのようだ)。

ただし、この結果だけで結論は出せない。コード品質との間でも強い相関を示しているからだ。例えば、Windows Vistaでは、TOTAL とリリース前の故障との相関係数が 0.84 となっているが、Size の相関係数も 0.75 と高い。コントリビューター数とサイズの間には関係があるだろうことは想像がつく。つまり、Ownership Metrics の各相関係数は、Classic Metrics に影響を受けた可能性があるということだ。

そこで、故障を目的変数とする多重線形回帰分析を行い、Classic Metrics のみを説明変数に含むモデルと、そこに Ownership Metrics の各種メトリクスを順に加えていったモデルを比較した結果が次の表となる。表内の数値は、故障数の分散のどの程度がメトリクスによって説明されるかを示している。

Base が、Classic Metrics のみを含むモデルだ。このモデルでは、Windows Vistaのリリース前の故障を 26% 説明できる。Base+TOTAL は、Base に対してコントリビューター数を説明変数に加えたモデルで、Windows Vistaのリリース前が 40% となり、Base と比較して 14% 改善していることが分かる。同様に、Base+MINOR のリリース前を見ると 46% であり、Base より 20% 改善し、Base+TOTAL より 6% 高い。つまり、コード品質を考慮してもなお、マイナーコントリビューター数がWindows Vistaのリリース前故障数に強い影響を与えていることが分かる。その影響の度合いは、トータルのコントリビューター数を使った故障数の予測より 6% 高い。

MAJOR や OWNERSHIP を追加したモデルも、Base+MINOR よりわずかな改善を示している。しかし表には記載されていないが、Base+MAJOR や、Base+OWNERSHIP に対して MINOR を追加したモデルは、追加前のモデルより大きな効果を示したようだ。つまり、メジャーコントリビューター数やオーナーシップより、マイナーコントリビューター数の方が、Windows Vistaのリリース前の故障数をより説明できるということだろう。

これらの傾向は、Windows 7のリリース後の故障を除けば、いずれもWindows Vistaのリリース前の故障と同じような傾向を示している。

以上のことから、マイナーコントリビューター数やトータルのコントリビューター数は、リリース前後の故障数に大きな影響を与えると言える。メジャーコントリビューター数や、オーナーシップもリリース前後の故障に影響を与えるが、その度合はマイナーコントリビューターやトータルと比べるとかなり小さい。

故障数を抑えるために何ができるのか?

どうすれば、マイナーコントリビューター数やトータルのコントリビューター数を低く抑えられるだろうか。

まず考えられるのは、ひとつひとつのコンポーネントのサイズを小さくしておくことだろう。サイズが大きいと、コードの変更に関わる開発者の人数も増える。そもそも、サイズが大きいという点からも品質が悪化する恐れがある。

コンポーネント同士の結合度を下げることも必要だ。マイクロソフトの調査結果では、あるコンポーネントのメジャーコントリビューターが、そのコンポーネントと依存関係にある別のコンポーネントのマイナーコントリビューターになることも明らかにしている。結合度を下げることができれば、コンポーネントをまたいだ変更の必要性も下げられるということだ。

また、結合度の強いコンポーネント同士については、同一の開発者がオーナーとなるよう組み合わせるのも良いだろう。そうすれば、オーナーとなった開発者は、どちらのコンポーネントにおいてもメジャーコントリビューターになるはずだ。

チームによるコンポーネントのオーナーシップ

このように整理していくと、安定した少人数の開発チームが特定のコンポーネントを所有するやり方が合理的であることがよく分かる。そうすれば、コンポーネントの変更に関わる開発者の人数も少なくなり、その顔ぶれも基本的に限定される。担当するコンポーネントに関する知識も深まるだろう。マーティン・ファウラー(Martin Fowler)の言葉を借りると、チーム内のメンバー同士は「コードの共同所有(collective code ownership)」であり、それぞれのチームとしては「強いコードの所有(strong code ownership)」だと言える。前者はエクストリーム・プログラミングのプラクティス「コードの共有(shared code)」の実践でもある。

フィーチャー開発において同時に変更されることが多いコンポーネントは、なるべく一括して同じチームが所有する。これなら、依存関係によって発生するようなコンポーネントをまたいだ変更も、チーム内で行える。アーキテクチャによっては、コンポーネントテストやデプロイの容易性が高まり、チーム間でのデリバリー衝突も避けやすくなるだろう。

こうしてひとつのチームに集められた複数のコンポーネントは、ビジネス機能を境界としたコンテキストを形成するはずだ。あるいは、コンテキストは異なっていても、ドメイン間の結合度が高いコンポーネントが集まる。サム・ニューマン(Sam Newman)も言うように、機能の変更とは、ビジネス機能の変更を指すからだ。もし、ビジネス機能ではなく、技術視点でコンポーネントを集めてしまうと、チームの所有権をまたいだコードの変更が頻発するようになる。これは、コストがかかる上にマイナーコントリビューターを生み出しやすい構造だ。

しかし時には、チームが抱えるバックログの実現のために、自チームが所有するコンポーネントのみならず、他チームが所有するコンポーネントを変更するケースも発生し得る。他チームのコンポーネントを変更する開発者は、マイナーコントリビューターだ。こういった場合、コンポーネントを所有する側のチームが、マイナーコントリビューターによって変更されたコードをしっかりとレビューする必要がある。これについての詳細は、過去の記事『開発組織を分散モノリスにしないチーム分割と協働のデザイン - mtx2s’s blog』の中で、「コントリビューター/コミッターモデルでのフィーチャー開発と協働」として書いた。

mtx2s.hatenablog.com

あまりにコンポーネントの数が多いと、どうしてもオーナーシップが低くなってしまうコンポーネントもでてくる。調査結果でも提言があるように、そういったコンポーネントを変更するときは、QAによる検証の優先度を上げるといった工夫も必要になるだろう。

最後に

はっきり言って、この調査で得られた結論に大きな意外性はなかった。しかし、経験的に理解していたことが、統計的に明らかになったという点は大きいと言えるだろう。

マイクロソフトの調査は、多くの企業の多くのソフトウェアプロジェクトを対象としたものではなく、Windos VistaWindows 7という、自社のソフトウェアプロジェクトに限定されていた。したがって、調査結果をそのまま様々なプロジェクトに一般化できるとは限らないだろう。しかし少なくとも、比較的多くの人が関わるソフトウェアプロダクト開発を抱える組織では、この結果を上手く活用できると考えている。