🐹

ニコ生方式のTODO管理術

2023/09/01に公開

ニコニコ生放送でフロントエンドエンジニアでを担当している @misuken です。

ニコニコ生放送のフロントエンドチームでは約1年前からTODOの管理方法を変更しました。
1年間運用してみて非常にうまく回っているので、変更前から変更後1年経った今に至るまでの流れを紹介していきたいと思います。

以前のTODO管理

長らくニコニコ生放送のフロントエンドチームでは実装途中のやり残しや、改善したほうが良いコードなどに対して TODO:*** のアノテーションを使用していました。

しかし、この運用を続けた結果以下のような問題が発生してしまいました。

  • 実装途中のTODOが埋もれて対応漏れがリリースされそうになる
  • あとでどのTODOから手を付けて良いかわからず結局手付かずになる
  • 解消されないTODOの影響でさらなるTODOを誘発する

レビュー時も、TODOがリリース前後のどちらで対応するつもりなのかわからなかったり、自身がTODOを書いた場合もリリースまでに直す必要のあるものを忘れないように気を張る必要があるなど、個人の注意力に頼るような運用になっていました。

現実的なTODO管理

現実を考えると、全てのTODOに対処すること、全てをissueでみっちり管理することはコスト面から見て現実的ではありません。かといって増え続けるTODOを見てみぬふりをしていては、日々の開発も保守も厳しくなり、開発者の負担も増してしまいます。

そこで、円滑に管理できて開発者の負担も少なくなるようなTODO管理ができないか検討を始めました。

前提条件

TODOの管理方法を変更する上で、いくつか前提条件を考えました。

TODOを管理することにコストを掛けたくない

しっかり管理するために定期的にTODOの棚卸しをするなど、TODOを消化するために今まで以上にコストを掛けていくことは避けたい。

これでは結局マンパワーで頑張っているに過ぎず、人的リソースの消費と引き換えにTODOを減らすことにほかなりません。

現状から切り替えるときに大変な方法は避けたい

現状から新しい方法に切り替える際、既存のTODOを全て確認したり、一斉に更新をかけるといった作業は行いたくない。

単純作業とはいえ、既存のTODOを分類したり、アノテーションの付け替えを行うなどの作業に時間を取られるとなると、誰もやりたくない作業になってしまいます。

リポジトリが1つならまだしも、大規模なプロジェクトでは複数のリポジトリを扱っているなど、そのようなコストも馬鹿になりません。

さらに同時並行で進んでいるタスクも複数あり、コンフリクトの影響も考慮すると煩わしいことがあると、チームの合意を得られなかったり頓挫する可能性が高くなります。

気軽にアノテーションを書ける状態は維持しておきたい

一般的には様々なアノテーションがあり、厳格にすればするほど情報としては質が上がります。

しかし、アノテーションを付けるときに悩んだり、レビューでアノテーションについて指摘が多くなったり、人によって見解が違ったりとなると、開発者の負担が大きくなります。

また、新しいルールが難しく感じるほど、そのルールより現状維持のほうが良いと考える人も出てくるので、新しいルールへ移行しにくくなってしまいます。

分析

すでに存在しているTODOや、日頃書いているTODOにはどのような傾向があるのか。
自分自身がTODOを書いているとき、どのような目的で書いているのかを分析してみました。

すると、大きくは2つ、細かくは3つの傾向があることがわかりました。

  1. リリース前に対処が必要なもの → リリースまでに絶対直すべき
  2. 保守上の問題になるもの
    1. 新たなコストを生む確度の高いもの → 早めに対処すべき
    2. 新たなコストを生む確度の低いもの → 早めに対処する必要はない

つまり、1のやり残しはリリース可能かどうかの判断に直結し、2は開発効率等の保守に影響するものと考えられます。

この1と2には大きな違いがあるので、まずはこれらが識別可能であることが重要です。

新たなコストを生む確度

次に2の新たなコストを生む確度に関して掘り下げていきます。

ここで言うコストとはわかりやすく言えば、そのコードを放置して1ヶ月後、3ヶ月後、1年後にそのコードを改善しておかなかったがために新たなコストがどの程度生まれるかのような考え方です。

わかりにくいコードであることによって、その周辺の実装に時間がかかったり、元々の問題によりさらにコード状況が悪くなって害が広がっていく二次的三次的なものも将来負担するコストと捉えます。

そこで以下の図のようにS〜Cの4つのランクに分けてどのように対処するかを分類します。

ランク タイプ リスク 望ましい対処法
S 早急に対応が必要 大きなコストに繋がる確度が高い。身近に迫ったリスク。 最優先で解消する。
A 注意が必要 いつか大きなコストに繋がる可能性がある。潜在的なリスク。 潜在的なリスクが増えないよう、しっかり把握して計画的に解消する。(ただし全て解消しなくても良い)
B しばらくは大丈夫 気にするほどのコストになったり害が広がる可能性は低い。 次回以降に手を入れる際、ついでに解消できそうなら解消する。
C 忘れても大丈夫 ほとんどコストに影響しない or コストに繋がる機会が来ない。 次回以降に手を入れる際、ついでに解消できそうなら解消する。

チームを1年間運用したとして、回収するために掛かったコストが将来負担するはずだったコストを上回れば、将来失うはずだった時間を得したことになるため、いかにその得を増やせるように立ち回れるかが焦点になります。

旬なタイミングと旨味

個人的にコードを改善するタイミングには旬があり、旬なタイミングで改善できると最大限の旨味を得られると考えています。

これは、積極的な投資のようなもので、得するものだけを見極めて連続して消化するゲームみたいなものと捉えると面白みも出てくるかもしれません。

S 早急に対応が必要

Sは直近の旬を逃したら大損害を受けることを意味するので、損害を受ける前の段階で早急に解消することに最大の旨味があると言えます。

A 注意が必要

Aはいつか大損害を受けるかもしれない状況ではあるものの、すぐに直面するものではなく、こればかりを優先してしまうと案件が進められないといった問題にも繋がります。潜在的なリスクが増えれば増えるほど実害に繋がる確率が上がるため、増えすぎないよう案件と案件の合間などに解消していくことに旨味があります。

ただし、全て解消することを目標にする必要はなく、案件とのバランスや将来的にコストに繋がる確度がどの程度あるかを吟味しながら適切なタイミングで解消していくことが大切です。

なぜなら、たしかにいつかは牙を剥くリスクとしては存在しているものの、当面そのリスクに直面する確度が低かったり、解消してはみたものの5年経って振り返ってみたら解消しなくてもコストに繋がっていなかったということも起こり得るためです。解消するタイミングが早すぎて費やしたコストを損したり、他の優先度の高いものに使えていたとなると、もっとうまく立ち回れていたことになります。

実際には解消のコストを費やして、問題が解消されたのち、解消されていたからコストが浮いたという段階に達して初めてプラスになるものではあるので、100%の精度では無いにしろ、どれから解消するか、まだ寝かせておくかの判断はしっかり行う必要があります。

明らかに負債化しているものの、あまり手が入ることはなく、数年後にその機能がまるごと不要になって削除といったパターンもあるため、Aは必ずしも早く対処すれば良い性質のものではないことに注意が必要です。

B しばらくは大丈夫 & C 忘れても大丈夫

これらはあまりコストに影響が無いものなので、これを管理したり解消するためだけに時間を割くこと自体が、将来受ける可能性のある損害を上回るロスになると考えています。

そのため、次回以降に手を入れる際、ついでに解消できそうなら解消するといった流れの中で解消されていくことに旨味があります。

簡単なものからやるは違う

TODOが溜まってくるとついつい簡単なものから手を付けたくなることもあるかもしれませんが、そうするとBやCの作業ばかりに時間を割いてしまうことがあります。

ほとんど旨味がなかったり、ロスのほうが大きい作業に時間を割くのは得策ではありません。

いかにして旬のタイミングで最大限旨味のある作業に投資し続けられるかどうかがトータルコストを抑え、将来の時間を作れるかの鍵になります。

ただし、BやCが多くなりすぎて他の作業に支障が出たり、開発効率が落ちているのであれば、そこには改善の旨味があるかもしれません。あくまで1ヶ月〜1年の単位で収支がプラスになる作業であるか、旨味がどれくらいあるのかを基準に行動すると良いでしょう。

新しいルール

これらを踏まえていくつかの方針を作り、その中から採用されたのが以下の新しいルールです。

  • UNDONE (新設)
    • 原則リリースされてはいけないもの、developブランチにマージするまでに解消する
    • PullRequest時にコード内にUNDONEが存在しているとリストアップして警告する仕組みを導入
    • issueを立てるかどうかは個人の自由
  • HACK (新設)
    • UNDONE以外の改善したほうが良いコード
    • 中でもコストに繋がりやすいもの(要はAに該当するもの)はissueを別途立てて別途回収する
  • TODO (既存)
    • 既存のTODOはHACK扱いとする (長時間残っているので事実上BやCに該当するということ)
    • 修正のついでに見かけたらHACKに寄せていく
    • 新規にTODOは書かない

これにより既存のコードはそのままに、以降UNDONEとHACKを使い分けるだけで良いため、開発者に負担の少ない形となりました。

以下はCIでUNDONEの有無によるレポートの表示です。
UNDONEがある場合は、その場所に直接飛べるようになっているので簡単に状況を把握できます。

導入初期

とてもシンプルなルールなので、チーム全体はスムーズに対応できました。

導入してみた印象。

  • 開発中は積極的にUNDONEと書いて作業を区切りやすくなった
  • 対応漏れのリスクが減って心理的な負担も少なくなった
  • 意思疎通が図りやすくなったのでレビューが楽になった

developブランチにUNDONEが含まれない運用になるため、開発中のやり残しは自分自身の書いたUNDONEだけになります。自身の作業中は仮データや仮実装に気軽にUNDONEを書けますし、どれだけ残っているかや回収しきったかも簡単に把握できます。

色々な面で心理的な負担がなくなったことで開発もレビューもスムーズになり、TODO管理の地味な負担や疲労から開放されました。

1年間運用してみた結果

新しいルールで1年間運用してみて、運用上目立った問題はとくにありませんでした。

PullRequest時のコメントで実装者がHACKに対して「ここissueにしておきました」や、レビュアーが「ここissueにしておいてください」のようなコメントが付いてAに該当するHACKにはissueが立って回収される流れが定着しています。

BやCの寝かせてあるHACKも、何か手を入れるときに「ああ、ここのコードちょっと問題あるんだなぁ」というヒントとして有効に機能する感じになっていたり、他作業の流れでサクッと回収できることも多く、狙い通りの旨味を得られています。

ある程度ルーズな運用でありながら、以下の要所を抑えたコスパの良い運用ができており、大変満足度する結果になっています。

  • リリースのリスクに繋がるもの
  • 開発や保守のコストに繋がるもの
  • 寝かせて良いもの

まとめ

  • 問題は4つのランクに分けて捉える
  • 旬なタイミングで旨味のあるものだけに時間を使う
  • TODO系のアノテーションは2種類があれば十分
  • 一部だけissueと併用することで管理コストを抑えられる
  • わかりやすく簡単なルールであることが重要

今回はニコ生方式のTODO管理術を紹介しました。
要所を抑えたコスパの良いTODO運用に魅力を感じる方は、この記事を参考にしてみてはいかがでしょうか?

株式会社ドワンゴでは、様々なサービス、コンテンツを一緒につくるメンバーを募集しています。 ドワンゴに興味がある。または応募しようか迷っている方がいれば、気軽に応募してみてください。

Discussion