見出し画像

技術的負債を管理するテクニック

原文:Managing Technical Debt
作者:Jeff Knecht
日本語訳:Hitoshi Tsuda

https://medium.com/slalom-build/managing-technical-debt-8594f03f1099

技術的負債をトラブルのもとにせず、強力なツールにするためのテクニックを紹介します。

ソフトウェア開発者は誰でも、望ましいが難しい方法の代わりに、簡単・単純・高速な方法で実装するという決断をしたことがあるでしょう。この選択は、将来的に手戻りが発生する可能性を生み出します。私たちは、この将来起こりうる手戻りを「技術的負債」と呼んでいます。

技術的負債とは悪く言えば必要悪であり、良く言えば強力なツールです。その良し悪しは、技術的負債がコードベースに導入される際の意図と、技術的負債がどれだけ適切に管理され、積極的に計画されているかによって決まります。

この記事では、技術的負債をトラブルのもとにせず、強力なツールとするために必要だと私が感じた10のステップを紹介します。

意図的であること

技術的負債は財務的負債と同様に、意図的に採用するのが最善の方法です。定期的なコードレビューと、あらかじめ定義されたプラクティスやパターンによって、偶発的な技術的負債を最小限に抑えることができます。そうすることで、技術的には理想的でなくても、競合他社よりも早く機能を市場に投入できるような、意識的な選択をすることができます。

自分のしている選択が理想的でないことを前もって理解しておくことは、製品にどれだけの技術的負債があるのかを適切に保ち、その負債に対する自分の許容範囲とのバランスをとる上で大きな助けとなります。

技術的負債に対する許容範囲は個人によって異なるため、全員が耐えられる技術的負債のレベルにチームが落ち着くには、少し時間がかかるかもしれません。コードベースの技術的負債の量と比較した場合の許容範囲について、チーム内で定期的にオープンな議論をするとよいでしょう。

技術的負債を把握する

意識的に技術的負債を負うことを決めた方が良いと述べましたが、まずは技術的負債を把握しなければ対処できません。技術的負債を効果的に管理するための重要な6つの質問を紹介します。

最初の質問
何が問題なのかを具体的にしてください。ファイル名、メソッド名、もしくは特定のコードセクションでしょうか。行番号は将来的に変更される可能性が高いので、コメントを使用するのがよいでしょう。

2つ目の質問
なぜそれが問題なのでしょうか。そのコードが何をやっているのか理解できる人がチーム内に一人しかいないから?パフォーマンスに重大な問題があるから?コーディング規約に違反しているから?それとも、単に読みにくいコードだからでしょうか?

3つ目の質問
具体的にはどう実装したら技術的負債を解消できるか提案できるでしょうか。

4つ目の質問
あなたの提案は既存の実装よりもなぜ優れているのでしょうか?具体的にどのように問題を解決するのでしょうか?また、まだ特定されていない他の潜在的な問題も解決しているでしょうか?

5つ目の質問
何もしないとどうなるでしょうか?

最後の質問
チームメイトや未来の自分に伝えておきたいことはありますか?どのような選択肢を検討し、なぜこの選択肢にたどり着いたのでしょうか?あなたが提案しているアプローチに関する詳しい情報は、コードベースのどこか、ブログの記事など、どこで見つけることができるでしょうか?

これらの質問は、特に小さな変更に対しては、答えることが多すぎるように思えるかもしれません。しかしもし変更がそれほど小さいのであれば、なぜ問題を見つけたときに対処しないのでしょうか?もし開発プロセスがそれを許してくれないとしたら、プロセスの変更を真剣に検討すべきです。また大きな変更については、これらの質問への答えすべてが、将来のスプリント計画、優先度の評価、および作業工数の見積もりに役立つことになるでしょう。

さらにもうひとつアドバイスがあります。もし課題管理システムを利用しているなら、この作業を別の課題タイプとして追跡してください。技術的負債は、ユーザーストーリーとバグの間の領域を占めています。これは、ベロシティレポート、キャパシティプランニング、負債レベルの管理を容易にするために重要な区別になります。さらに、他の課題タイプでは関連性や有用性がないような情報を収集し、カスタマイズすることも可能です。

見積もりをする

技術的負債は、機能実装と同じ尺度で見積もりしたりサイズ設定されるべきです。アジャイルチームではストーリーポイントで見積もることが多いでしょう。共通の尺度に基づいた見積もりは、予算編成、ベロシティレポート、スプリント計画を容易にします。

バックログのサイズに影響を与えるという懸念から、技術的負債の追跡にストーリーポイントを使用することに反対する人もいます。しかし(すでに述べた通り)もしカスタム課題タイプを作成できたなら、技術的負債バックログを機能的バックログから簡単に分離することができ、同時に見積もりプロセスや技術的負債をスプリントに入れ込む能力において、ある程度の一貫性を持たせることができます。

少し警告しておくと、技術的負債に対処しない期間が長ければ長いほど、負債が大きく、複雑になる可能性があります。運が良ければ、ライブラリのアップグレードや機能の非推奨化によって技術的負債が解消されることもありますが、それを前提に技術的負債の管理戦略を立てるべきではありません。

優先順位づけをする

すべての技術的負債が同じように作られているわけではありません。ある項目は、他の項目よりはるかに大きな影響を与えるでしょう。私は、以下の4つのシンプルな優先順位付けをお勧めします。

  1. 早急に行う必要がある項目 これには、重要なパフォーマンスの最適化、インフラのハードニング(要塞化)、セキュリティの修復などが含まれる場合があります。

  2. 次回のリリースまでに行うべき項目 このカテゴリの項目は、システムのサポート性、または次のリリースで計画されている新機能の実装を促進するリファクタリングに関連すると思われます。

  3. 次のリリースの後でも、いつでも実行可能な項目 例えば、大きなモジュールをより小さなコンポーネントに分割したい場合や、セキュリティ、パフォーマンス、機能的な理由から必ずしも必要ではないライブラリのアップグレードが考えられます。

  4. 取り組む価値があるか怪しい項目 この項目に対応することで得られる影響は、対応コストに見合うだけの価値に見合うかどうか微妙なところです。

技術的負債は、機能的な実装とはある程度独立して優先順位付けされるべきですが、重複する部分もあり、ユーザーエクスペリエンスに影響を与えるような変更(例えば、パフォーマンスの最適化)の場合はプロダクトオーナーと協力する必要があると思います。

多くのアジャイルチームは、このような評価の代わりに、優先順位付けのためのシンプルなスタックランキングを活用しています。優先順位のタグ付けを追加することで、技術力の高くない役員にも報告しやすくなるため、私は上記4つの優先順位づけとシンプルなスタックランキングを組み合わせるのが好きです。

結局、優先順位付けの方法は状況に応じて変わりうるのです。

計画を立てる

一般に、優先順位1位の作業は、優先順位2位の前に完了させるべきです。ただし、作業に取り組むのに適したスキルと、そのスキルを持つチームメンバーについて考慮しなければなりません。たとえば、ネットワークに関連した作業(優先度高)と、フロントエンドコンポーネントの作業(優先度低)がある場合、担当者が別々に割り当てられるのであれば2つの作業を同時に取り組んでも構いません(ただしそのフロントエンドの作業が専門家が必要な難しいタスクである場合などは、無理に取り組む必要はありません)。チームがこのような計画をできるようにする1つの方法は、作業を完了するために必要なスキルに基づいてバックログの各項目にタグ付けすることです。

検討する項目の大きさを考慮することも重要です。スプリントでは、優先順位の高い1つの項目を追いかけるよりも、優先順位の低い小さな項目を数多く取り組む方が合理的な場合があります。チーム全体のベロシティや士気の面でも、1つの項目よりも、低いところに実った果実を多く集める方が、大きな影響を与えることがよくあります。

また、優先順位の高い項目は、将来のスプリントで計画されている機能作業に関連するために後で取り組む方がよい場合があるかもしれません。あるいは優先順位の低い項目でも、すぐにそのコード領域で作業するのであれば、早く取り掛かる方が理にかなっているかもしれません。

優先度4の取り組む価値があるか怪しい項目は少し線引きが難しいところです。これらの項目は、実装が容易で、たまたまその部分のコードに触れることがない限りは、優先順位の高い項目がすべて完了するまでは考慮されるべきではないでしょう。

要するに、「優先度」はスケジュールを立てるための良い目安にはなりますが、それだけで判断してはいけないのです。現実的にはさまざまな要素を考慮する必要があるのです。

予算管理をする

技術的負債を本当に回避する方法はプロジェクトを中止すること以外にありません。無視したり、負債への対応を計画する必要がないと考えずに技術的負債をあらかじめ見込んで対応しなければなりません。

技術的負債に取り組むために、各スプリントで一定の時間を確保してください。計画したスプリントベロシティの15%が良い出発点です。時間をかけて、あなたのチーム、納期、優先度の高い負債のバックログ、そしてあなたの許容範囲に適したレベルをもとに、この時間を調整することになります。

なお、これによって製品のデリバリーが遅れることは(おそらく、直感に反して)まずありません。予算化されているかどうかに関わらず、チームは技術的負債に対処していきます。もし予算化されておらず、計画されていない場合、予測困難なベロシティの低下として影響が現れます。

予算化することで、プロジェクトのデリバリー期間中、ベロシティはより安定し、開発チームはコードベースをクリーンに保つための計画を前もって立てることができるので、より満足するでしょう。これらが相まって、次のリリース準備が実際にいつできるのか、そしてそれがどの程度サポート可能なものなのかについて、より明確なイメージを持つことができます。

私のアドバイスとしては、早い段階でプロダクトオーナーとこの話をし、最初から計画を立てておくことです。

習慣化する

真の職人というのは、どんな仕事でも "Clean as you go" (行くところすべてきれいに), を信条としています。これにはちゃんとした理由があります。作業を進めるための環境が整っていると、作業がしやすくなるのです。

技術的負債に取り組む際の私のアドバイスは、毎回のスプリントに技術的負債への取り組みを計画することです。

できればハードニング・スプリント(品質改善を行うスプリント)のみで技術的負債に取り組むことは避けてください。私はハードニング・スプリントを定期的に設けるチームを見てきました(例えば、4回か5回のスプリントに1回)。これは、スプリント中の技術的負債に対処するための定期的な予算と組み合わせれば、素晴らしいアイデアです(ただし、おそらくやりすぎであることは認めます)。もし毎回のスプリントに技術的負債への作業を織り込むことに同意が得られない場合は、ハードニング・スプリントを設ける方が、全く何もしないよりはマシです。しかし、このアプローチは開発チームにとってより困難なものとなる可能性があります。

最初の困難は、定期的に新機能のデリバリーを停止することをプロダクトオーナーに納得してもらうことです。一般的に、コード品質に継続的に対処する持続可能なベロシティを確立することは、ビジネスパートナーを説得するよりもはるかに簡単です。そうでないと、4、5回のスプリントを高速で実行した後のハードニング・スプリントでは、ビジネスパートナーから見ると、すでに正常に機能しているものを立ち止まって書き直しているだけに見えるでしょう。

2つ目の困難は、大きな技術的負債がある一方で、そのスプリントのすべての機能実装の作業が同じ技術的負債に悩まされている可能性があることです。チームは、理想的でないと分かっているパターンを使って作業しており、実際には問題のあるコードの山を増やしているのです。

3つ目の困難は、変更の必要性に気づいたときから数スプリント待たされることで、問題からの距離という点でコストが発生することです。その問題に対処する頃には、問題が大きくなっていたり、修正の勢いが失われていたりする可能性があります。おそらく、もっと早く問題に対処した場合よりも、作業を完了するのに時間がかかるでしょう。

4つ目の困難は、欠陥の解決とパフォーマンス向上がハードニング・スプリントを支配してしまう可能性があることです。このため、技術的負債に対処するための時間があまり残らない可能性があります。

さらに、チームが「ハードニング・スプリントを行う時間はない」と判断してしまうリスクもあります。プロジェクトの期限が迫ってくると、「不要な」作業を排除しようとする強い動機が生まれ、ハードニング・スプリントは効率化のための初期の犠牲者となることが多いのです。

監視する

計画を実行した後は、技術的負債がどの程度発生し、どの程度の割合で返済されているかを監視しましょう。

スプリントごとにどれだけの技術的負債が作られ、取り除かれ、完了し、優先順位がつけ直されたかを記録してください。優先順位ごとに記録することで、チームが適切なタイミングで適切な項目に取り組んでいることを確認でき、物事が手に負えなくなっていないかどうかを確認することができます。

これを継続的に監視することは、技術的負債バックログ(特に優先度の高い項目)を管理するために、スプリント予算が適切かつ十分であることを保証するために重要です。バックログが時間とともにどのように変化しているかを知ることで、各スプリントで最も優先度の高い項目に取り組む時間を多く計画すべきか、少なく計画すべきかを知ることができます。

技術的負債のバックログが増え続けている場合、持続不可能なベロシティで機能を提供するために、チームが手を抜きすぎていることを示すかもしれません。逆に、バックログが急速に縮小している場合は、技術的負債に対する予算が必要以上に積極的であることを示している可能性があります。どちらの場合も長期的なリスクを表している可能性があり、プロダクトオーナーと会話をする上で役に立ちます。

レビューする

技術的負債の管理で特に難しい点は、その予測不可能な性質とは別に、既存の技術的負債の優先順位と規模が時間の経過とともに変化しうることです。かつては数行のコードに対する小さな、比較的重要でない微調整であったものが、すぐに実行しなければならない大手術に簡単に発展し、さもなければ次の主要機能の実装が不可能になる可能性があるのです。

このような問題が突然発生する前に対処するため、チームの技術リーダーは警戒を怠らず、定期的に技術的負債バックログを見直し、優先順位を付け直すことが重要です。

調整する

すべてのアジャイルデリバリープロセスと同様に、何がうまくいっていて何が改善できるかに基づいて、定期的に調整する必要があります。

各スプリントにおける技術的負債への作業の予算は、バックログの現在の状態を反映するために定期的に調整されるべきです。良いアプローチは、チームが納得できる技術的負債のレベル(おそらくユーザーストーリーバックログの割合)を特定し、優先度の高い未処理の負債のレベルが比較的安定したレベルにとどまるように、予算を調整することです。さらに、予算を前倒しする必要がある場合もあるでしょうし、他の作業を優先して技術的負債の作業を延期する必要がある場合もあるでしょう。

技術的負債の項目の見積もりは、システムの規模や複雑さが変化したときや、重要なアーキテクチャ上の決定が導入されたときに、定期的に調整する必要があります。

技術的負債をバックログに追加するときにどんな情報を集めるかは、チームが決めた価値基準に従って調整されるべきです。

優先順位は定期的に調整しましょう。最初に特定したときは優先順位が低かったものが、製品リリースが近づいたり、機能の優先順位が変わったりすると、最優先になることがあります。

新しいものだけでなく、バックログに残っているものに対しても柔軟性と警戒心を維持することは、技術的負債に対応すること以上に、技術的負債を管理するための重要な要素です。

技術的負債を見込むとき、何を期待するか

よく、「技術的負債をどの程度見込むべきか?」と聞かれることがあります。これは、「文字列の長さはどれくらいですか」と聞くようなものです。

本当の答えは、定量的よりも定性的なものです。技術的負債のレベルは、ビジネスのニーズを満たすためのチームの動きを遅くしていませんか?バックログにある技術的負債の種類によって、眠れない夜を過ごすことになっていませんか?「コードベースがひどく汚い」という理由で、誰かが激怒して辞めたことはありませんか?これらの質問に対する答えのいずれかが「イエス」であれば、問題があることになります。

定量化が難しいのは、(a) コードベースがそれぞれ異なること(例えば開発初期フェーズとレガシーなコードベース)、(b) 技術リーダーによって技術的負債に対する許容度が異なること、(c) 技術的負債バックログの構成、構成、変化率がプロジェクトのそれぞれの段階によって異なることが挙げられます。

初期の開発フェーズでは、技術的負債の量と優先度の両方が大きく、散発的に変化する可能性があります。チームは、ある機能を早期にプロダクトオーナーに見てもらうために、「迅速かつ汚い」ことを行うかもしれません。この段階では、コードベースを綺麗に保つことには過度に注力せず、技術的負債の量と優先度がどのように変化するかを見極めるのが良いでしょう。このフェーズで重要なのは、技術的負債が発生したり気づいたりしたら、すぐにそれを捕捉する習慣をチームが身につけることです。

開発の中盤、つまり開発チームにとって時間の大半を費やす段階になると、技術的負債の量は一定になるはずです。健全なプロジェクトでは、技術的負債の発生と対処が同じようなペースになると考えられるからです。チームが大規模なリファクタリングの実施を決定した場合、負債の量にぶれが生じる可能性がありますが、十分に時間が経過すれば、負債の量はほぼ一定に保たれるはずです。そうでない場合は予算を調整する必要があるかもしれません。

プロジェクトの終盤になると、バックログに占める技術的負債の割合が高くなります。これは、未完成の新機能の数が減少し、技術的負債の量が残りのバックログに占める割合が自然に大きくなるためです。

まとめ

この記事では、技術的負債をより可視化し、管理しやすくするためのプロセスを紹介しました。このプロセスによって、チームの機能デリバリー速度がより安定し、予測可能になり、コードベースの品質が向上し、そのコードベースの保守と構築を担当するエンジニアの満足度を最大化することができるようになるのです。

Thanks to Omar Galeano and Hitoshi Tsuda!


この記事が気に入ったらサポートをしてみませんか?