例え話だけで解決に向かうのか? - 技術的負債論

はじめに

以下のエントリがHOTになっています。公開4日後の現在で949はてブです。

技術的負債という(非エンジニアにとっての)隠しパラメータが生産性100倍を起こす - mizchi's blog

私は企業で Software Engineer in Test としてソフトウェアの保守性に責任を持つポジションに就いている身ですのでこのテーマに関心があるのはよいことだとは思います。技術的負債そのものについてのエントリは過去にも沢山あるようですが、mizchi さんのエントリは誤解を恐れないシンプルで断定的な書き方ですので多くの人に刺さったのでしょう。

ただ、技術的負債(technical debt)というメタファーが万人に誤解無く伝わるのかは疑問です。時間を借りているのかはピンと来ませんし、財務的負債と異なり返済の義務はありません。また、エンドユーザーに提供する価値よりも負債にフォーカスしてしまうのではないかという懸念があり、以下のツイートと同様の感想を覚えています。

このエントリでは技術的負債のより良い例えを再考し、問題視されていることを解決する指針を示したいと思います。本来1エントリに収まるテーマではなさそうですが、書いてみることにします。

なぜ例えが必要なのか?

例えが必要なのは「誰か」に理解して欲しいから。順を追って考えてみます。

まず技術的負債とは端的な説明をすると、ISO/ICE25000シリーズで言う内部品質における保守性が低いソースコードのことです。読むのに時間がかかる・勘違いしやすい・意図しない影響を生みやすい・テストしにくいという特徴を持ち、バグが生まれやすくなると考えられます。*1

そして、この問題に気づくためには、ソースコードから保守性を感じるスキル(できれば測定するスキル)と、保守性が開発効率と利用時品質に影響することの理解が必要です。

問題に気づいて保守性を向上させようとすると、すなわちリファクタリングが必要になります。当然ながら悪いものほど良くするのが難しく、リバースモデリングスキルとリソースの確保が重要となります。そもそも保守性の低いコードを生まないためのスキル・プロセス、およびそれらを育てるためのリソースも必要になります。

つまり、低保守性の問題に気づいたエンジニアは

  • エンジニアに対して「スキルを覚えてください」
  • プロジェクトマネージャーあるいは経営層に対して「リソースをください」

と要求したくなるでしょう。

しかし、低保守性に気付いて問題視するには前述したスキルと理解が必要で、要求が受け入れられるとは限りません。特に後者に何とかして伝えるためにはエンジニア以外にも伝わる言葉を使った方が有効でしょう。そこで「技術的負債」という言葉が生まれたと考えられます。*2

「健康リスク」というもう一つの例え

技術的負債の生みの親であるウォード・カニンガム氏は、保守性を高める設計を考える時間を省くことを「時間を借りる」、低保守性のコードと付き合うことを「利息を払う」、リファクタリングすることを「返済する」と例えています。

良い気もしますが、保守性が一定以上のコードを生むのに必ずしも時間がかかるわけではないと思いますし、負債というと「返さなければならないもの」と誤解される恐れも懸念されます。技術的負債という言葉は WyCash というポートフォリオ管理システムの開発にて生まれたので、周囲の理解が得られたのではないでしょうか?もっと万人向けの例えは無いのでしょうか?

といったところで「健康リスク」です。通じるかどうかは相手次第ですが、私的には「健康リスク」の方がより多くの方に誤解無く伝えられると思います。いかがでしょうか。*3*4

健康リスクがある → 病気になりやすい 保守性が低い → バグが起こりやすい
健康リスクを避ける習慣:タバコとお酒はほどほどに・よく寝る・手を洗う・歯を磨く・栄養バランスの良い食事をとる・運動する 保守性を高める習慣:OOなどの設計手法・TDD・リファクタリング・レビュー・フォローアップ・lint・バージョン管理・インシデント管理・ドキュメンテーション
健康リスクを高める習慣があっても、病気になるとは限らない。 保守性が低かったとしても、バグが起こるとは限らない。
わかっちゃいるけどやめられない わかっちゃいるけどやめられない
ハードボイルドに生きる ハードコーディングする

ソフトウェアメトリクスを用いた正攻法

例え話を持ち出したのは

  • エンジニアに対して「スキルを覚えてください」
  • プロジェクトマネージャーあるいは経営層に対して「リソースをください」

という要求を満たすためでした。エンジニア個人レベルの問題なら理解だけで解決に向かうかもしれませんが、集団に理解を求めてアクションを期待する場合はプラス何かしらのプッシュが必要になることでしょう。また、リソースを求める場合は理解の有無によらず「どれくらい必要?」と返ってくることでしょう。ROIも求めないといけないかもしれません。

これに答えるためには、

  • 保守性の定量化
  • 開発対象における保守性とバグの相関算出
  • 保守性向上を行った場合に回避できるであろうバグの修正コスト算出
  • 保守性向上を行った場合に発生するであろうバグの修正コスト算出
  • 保守性向上のための設計・コーディングコスト算出

をやるのが正攻法と考えられますが、なかなか真正面から取り組むのは難しいでしょう。そこで頼りになるのが先人の研究成果です。残念ながら私は沢山の研究事例を知っているわけではないのですが、知る限りで一番近いのが昨年に公開されたMITのD論でIron Bridge Software社の事例を研究したものです。*5

  • 手続き・構造共に複雑な箇所を変更すると、0.414件のバグが発生することが予測される。
  • 手続き・構造共に単純な箇所を変更すると、0.059件のバグが発生することが予測される。
  • 最も構造の複雑なソースファイルのバグ密度は、最も単純なそれの3倍。
  • 複雑な箇所の担当に回されると生産性は半分になり、離職率は10倍になる。

という興味深い数字が出ています。保守性の重要性を説くだけならこれだけで十分なのではないかと思います。

「よその事例だけじゃなくて、うちではどうなのよ?」と聞かれるかもしれませんが、ツールで測れる保守性に関するソースコードメトリクスを適当に選んでバグ数との関係を散布図にプロットして相関係数を算出するだけならハードルはそんなに高くありません*6。コストの算出まで踏み込む場合はやったことがないのですが、経験的なバグあたりの修正時間・関わる人々・人件費を用いればなんとか求められるのではないかと考えています。

保守性に悩む現場では上記のような定量化を試みて発表してくれたらなと願います。*7

まとめ

  • ソフトウェア開発における技術的負債とは保守性の低下したソースコード
  • 低保守性はエンジニア以外には伝えにくいので「技術的負債」「健康リスク」という比喩を使う
  • 例えだけでは不十分な場合は定量化をやっていこう

*1:9126 ではプロセス品質→内部品質→外部品質→利用時品質 の影響を説明するわかりやすい図があったが25000では無くなってしまった。実はある?私が知らないだけだったりして。

*2:"technical debt" の生みの親の文章からもそう読み取れる http://c2.com/cgi/wiki?WardExplainsDebtMetaphor

*3:健康や病気に例えている例は早稲田大学の岸知二教授からJEITAのワークショップで聞いたことがある http://home.jeita.or.jp/cgi-bin/page/detail.cgi?n=646&ca=1

*4:ソフトウェア病理学という昔の本が参考になりそう http://www.slideshare.net/mori_ryuji/sig-26157700

*5:http://dspace.mit.edu/handle/1721.1/79551

*6:どんなメトリクスを選ぶのか、相関があるように見えるだけじゃないのか、など考えると難しい

*7:SQiP, JaSST, IPSJ SIGSE, JSSST とかでしょうか。私もそのうち。