TT Lab
はじめる
学ぶ 学習パス コース

開発者の起業 — 作る前に検証する

技術的負債とリリース速度 — 利息を測り返すときを決める

TT Labで続きを見る

一言でいうと

技術的負債は、悪いものではなく、利息が付く借入です。初期の製品は、速く学ぶために、わざと借ります。問題は、利息を測らないことです。デプロイ記録と作業記録から、利息(計画外に漏れる時間)とデプロイの安定性を測り、返すコスト・回収期間・先送りされる機能の価値を、1行に並べれば、「今返すか」が、意見ではなく計算になります。

なぜ必要なのか

小さなチームは、2つの声の間で揺れます。「今直さなければ、永遠に直せない」と、「顧客が望む機能から出さなければ生き残れない」です。どちらも正しい言葉なので、会議が終わりません。結論は、たいてい、声が大きいほうが決めます。

マーティン・ファウラーは、技術的負債の記事で、このメタファーを、ウォード・カニンガムが1992年のOOPSLAの経験報告で作ったと書き、コードの欠陥のせいで、機能を加えるたびに追加でかかる労力を利息、その欠陥を取り除く労力を元本と説明しています。その枠組みをそのまま使えば済みます。利息が大きく、増えているのに、元本が小さければ、返すほうが速く、利息が小さければ、その時間に機能を出すほうがよいです。

どう動くのか

デプロイの安定性: DORA指標: dora.devの指標の案内は、スループットの指標として、変更のリードタイム(バージョン管理にコミットされた変更が、本番にデプロイされるまでの時間)・デプロイ頻度・失敗したデプロイの復旧時間を、不安定性の指標として、変更失敗率(デプロイの直後に、すぐ介入が必要だったデプロイの割合)と、デプロイの手戻り率(本番の障害のために行った、計画外のデプロイの割合)を挙げています。負債がたまったモジュールは、しばしば、デプロイが間遠で、失敗が多く、復旧が長く、障害対応のデプロイが多いです。

平均より中央値: リードタイムには、数日ずつ寝かされた変更が数件混ざります。平均は、その数件に引っ張られて、典型的な変更がどれだけかかるかを覆い隠します。このラボは、中央値と平均を並べて書き、違いを見られるようにします。

利息を測る: 週ごと・モジュールごとに記録した「計画外の作業時間」(バグ・障害対応)が、利息です。平均だけを見ず、トレンドを見ます。最初の4週間と最後の4週間を比べて、増えているなら、返す決定の基準は、過去の平均ではなく、最近の利息でなければなりません。

返すかどうかを判断する: このラボは、次の順序で計算します(すべての値とルールは例です)。

値 計算
節減(時間/週) 最近の利息 × リファクタリングが減らす割合
回収期間(週) リファクタリングのコスト(時間) ÷ 節減
期間の純節減(ウォン) (節減 × 判断の期間 − コスト) × 1時間あたりのコスト
遅延コスト(ウォン) (コスト ÷ チームの週あたりの容量) × 機能の週あたりの価値

リファクタリングしている間、チームが機能を作れなければ、その分だけ機能が遅れ、その機能が毎週稼いでいたはずの価値が失われます。これが、遅延コスト(cost of delay)です。回収期間が最も短い候補の、期間の純節減が、遅延コストより大きければ、先に返し、そうでなければ、機能を先に出します。「リファクタリングが利息を70%減らす」のような見積もりは、間違うことがあるので、見積もり値を書いておき、返した後の実際の利息と比べるところまでが、1周です。

負債をどこに記録するか: 利息を測るには、計画外の作業を、モジュールごとに記録しなければなりません。大がかりなツールは必要ありません。イシュートラッカーに、「計画外」の印とモジュール名、費やした時間だけを残せば、週ごとの合計が出ます。記録がなければ、利息は「みんな忙しい」という感覚としてだけ存在し、感覚は、機能リクエストの数字に勝てません。

すべての負債を返す必要はありません: もうすぐ捨てる実験コードや、ほとんど変わらないモジュールの負債は、利息が0に近いです。ファウラーが言うように、利息は、そのコードを変更するときに付きます。そのため、返す候補は、「汚いコード」ではなく、「頻繁に変更されて、計画外の作業を生むコード」から選びます。変更頻度と計画外の作業が、ともに高いモジュールが、最初の候補です。

現場での姿

間違いに気づく方法

次のラボですること

12週間のデプロイ・作業記録で、サービス別のDORA指標を計算し、リードタイムの中央値と平均がなぜ違うのかを見ます。モジュール別の利息とそのトレンドを測り、リファクタリング候補2つの、回収期間・純節減・遅延コストを計算して、ルールどおりに決定します。採点ツールは、あなたの関数を、揺さぶった記録でも再実行します。