TODOは実は「処理するためのもの」ではない
(sophiebits.com)- 一部のチームは、すべての TODO コメントをバグトラッカーに登録したり、1年以上経過した TODO を自動削除したりする方針を採っているが、こうした慣行は推奨されない
- TODO コメントは、必ずしも完了してこそ価値があるものではなく、コードを書いた時点の文脈やアイデアを残す脳のスナップショットとして機能する
- 重要な TODO はイシューとして管理すべきだが、その大半は優先度が低い、あるいはエッジケースを記録するメモである
- 適切に配置された TODO は、将来コードを読む人が「この部分をリファクタリングしてもよいか?」と考えるとき、当時の作者の意図を把握する手がかりを与える
- TODO の価値は、完了されたかどうかではなく、文脈・意図・可能性を記録し、将来の保守やコラボレーションに役立つ点にある
TODO コメントは、必ず処理しなければならないのか?
- 一部の組織では、コード内のすべての TODO をバグトラッカーに登録したり、一定期間(1年以上)が過ぎると自動削除したりするルールを適用している
- しかし、このようなアプローチは実際には非効率的であり、TODO の本質を見落としている。つまり、実際に処理されて初めて価値が生まれるわけではない
TODO の本当の価値
-
たとえば、
// TODO: 다음 주 출시 전에 이 파일의 뒷부분을 완성해야 함のようなコメントは、実際にトラッキングが必要かもしれない
-
しかし、良い TODO はたいてい、
// TODO: 사용자가 이 버튼을 트리플 클릭할 경우, 핸들러에서 \[xyz] 오류 발생のようにエッジケースを記録したり、今すぐにはできない構造改善のアイデアや見落とした状況などを、文脈とともに記録するために使われる
TODO は「計画」ではなく「窓口」
- ほとんどの TODO は、実際にはすぐに対処する必要のない低優先度のものだ
- 書いた時点での作者の悩みや判断、コンテキストを将来のコード読者へ伝える役割を持つ
- 後になってコードを読む人が「ここは構造を変えてもよいのか?」と考えるとき、TODO は当時の作者の意図を把握する助けになる
よく書かれた TODO の効果
- コード内の TODO は、ときに問題になりうる点、構造改善の可能性、未処理のエッジケースなどの重要なヒントを与える
- 必ずしも解決のための計画でなくても、コラボレーションや保守において微妙な文脈の共有に大きな役割を果たす
- 結局のところ TODO コメントは、コードの理解しやすさと今後の保守性を高める貴重な記録である
結論
- TODO は、必ず完了してこそ価値を持つのではなく、作者の考え・意図・コンテキストを残し、未来のコード読者とのコミュニケーションの窓口になる
1件のコメント
Hacker Newsの意見
マージ前にTODOを処理する方法は3つあると思う
1. イシューを残す―本当にやるべきことなら20秒ほどかけて記録し、トラッキングするとよい
2. その場で片づける―イシューにするには小さすぎることなら、コミット前に解決する
3. コメントに変える―直す価値もなく、トラッキングも不要だが覚えておきたいなら、通常のコードコメントとして残すのを勧める
健康のためにブロッコリーを食べるように、TODOもトラッキングする習慣を持つのがよい
外部システムに登録されたイシューは、その部分のコードを触る開発者の目に入りにくいことがある
簡単に直せるようなものまでわざわざトラッキングするコストがもったいないなら、TODOとして残すほうが効率的だ
コード内のTODOは、そのコード作業時にひと目で見え、リファクタリング時にも簡単に削除できる
だがTODOコメントと通常のコメントの違いを明確に述べていない点は惜しい
TODOという語そのものに視覚的な強さがあり、どんな種類のコメントかすぐ分かる
TODOコメントをわざわざ「TO DO(やること)」として受け取らなくてもよいと主張するのは、少し疑わしい
記事の意見にはおおむね同意するが、むしろ普通のコメントとして残すほうが改善だと思う
チケットシステムに載せるなら20秒以上かかるうえ、役立つどころかむしろ気を散らす原因になる
// TODO: improve the routing https://jira.com/whatever/TIX-1234
理由は、コメントが孤児になると、なぜ残されたのか誰にも分からなくなるからだ
単にコメントだけ残すと、後で誰かが用途や背景を忘れてしまう
だから必ずチケットを作るか、その場で処理すべきだと思う
FIXME: 明らかに間違っている、または壊れている部分。最優先
XXX: 見た目が悪い、または誤った前提が入っている部分。高優先
TODO: いつかまったく新しいアプローチ/カテゴリ/分岐を実装すべき部分
NOTE: 単なるコメントよりも重要な情報伝達用
私は主にレガシーで保守されていないコードエンジンで働いていて、ここでは「コードが真実」なのでJIRAは作らず、読んでいる途中でその場その場で直していく
TODO: リリース前までに必ず必要な作業、必須事項。該当しないなら別カテゴリへ移すべき。リリースを止める要素
FUTURE: いつかTODOになるかもしれないもの。たいていは構造設計など任意の要素
MAYDO: あればよいが、なくても構わない
PERF: もっと性能が必要になったときにやるとよい
さらにドメイン関連の意味タグも使っている
私の意見では、TODOはコードスメルではなく、コードベースの重要な部分に自然に蓄積していくものだ
本気でやるなら、CIでその文字列を含むコードをrejectするように設定する
その意味では、XXXが私にとって最優先だ
優先度を上から並べると
FIXME: 集中を保つためのもの。これを解決して初めてマージまたは完成扱いになるコード
XXX: すぐ直すべきもの。今は動くが、近いうちに修正が必要
TODO: 後で再訪すべきもの。コードは十分に使える。XXXより低優先
NOTE: 特異点や知っておくべきことを説明し、後続の作業者を助ける
TODOはリファクタリング/性能/明確性の改善といった、可能な作業項目を残す用途だ
NOTEは過去の情報や、その場で見ても分かりにくい思考の流れを残す用途で使う
チームで働く前提ならなおさらだろう
だからといって意味がないと言いたいわけではない―こうしたツールがある、あるいは作られる必要があると思う
こうした技術的負債やコードスメルは、本当はもっとよく追跡・記録・説明されるべきだが、JIRAのような生産性を落とす作業を求めると、かえって何も記録しなくなってしまう
少なくともコード内にTODOがあれば、どこかには残る
TODOは実際に「やること」でもあるのだから意味がある
「もっと良くできると分かっているが、そのためにわざわざ流れを止めない。機能が壊れるわけでもなく、あれば少し良くなる程度だ」
エディタのTODOハイライトがたまに目に入ったとき、少し直したくなるのに役立つ
とはいえ、ほとんどのTODOは一生残るか、実際にはほとんど解決されない
JIRAやGH Issuesなどに登録しても、最終的には記録が結びついている必要がある
そして参照だけ残すと後で意味を失うことがあるので、コメントに説明も一緒にあるべきだ
多くのコミットは実際には内容をうまく伝えていない
昔ながらのやり方でTODOを残す代わりに、より良いツールの利用を促したい
多くの開発者はコミット頻度が低すぎて、一度に複数の作業をまとめて入れてしまう
コミットメッセージも
updating somefile.pyのような意味のないものになりがちだ私のコードベースでは、TODOはここで説明されている通りに使われている
TODOは実装の説明、特に欠けている部分を文書化するためのものだ―必ず対処すべきという意味ではない
私の考えでは、コード自体に実際のToDoリストを残すのはあまり意味がない。優先順位は常に変わるので、書いた時点では重要でも実際にはそうでないかもしれないし、思ってもみなかった問題が後から解決すべき事柄になることもある
TODOコメントを更新するためだけにPRを出し続けるわけにもいかない
やることを書きたいなら、イシュートラッカー、あるいは簡単に更新できるテキスト文書など、外部で管理するほうがよい
さっきも #TODO で、ごくまれにしか起きない例外的な状況を記録しておいた。2年間実際に起きたことはないが、後で自分がなぜこの部分に対処しなかったのか知りたくなったときに役立つ
こういうものは単なるコメントとして残すべきだという人たちの言い分も分かる。コードベースの性質次第で、私のような2人チームではTODO方式がうまく合う
// TBD: [...]をこういう用途に使っていた。TODOにこだわる人たちに気づかれないようにするための小技だ実際に直す予定はないが、後で時間ができたときにもしかして整理できるかもしれないので、一度くらいctrl-Fで探してみる価値があるものだ
TODOをコードスメルとみなすツールやプロセスが多すぎるのは不合理だと思う
結局は優先順位の問題で、最終的には割れ窓(Pragmatic Programmerの有名な比喩)だと思う
本当に直さないと決めたのなら、ソフトウェア文書に記録するほうがよい
たとえば単に
// If the user triple-clicks this button, the click handler errors because [xyz]
とだけ書くと、これがバグなのか、あるいは元から意図された動作なのか明確ではない
TODOは「ここには不完全な部分があるので、作業するときの参考にしてほしい」という簡単なシグナルだ
必ず解決すべきことなら、別の場所でトラッキングするのが正しい
しかしTODO自体を減らそうとすると、かえって文書化されていないコードが増えるだけだと思う
その時間があるなら、そのバグをその場で直すか、あるいは「トリプルクリックは [xyz] のため無視される」といったコメントを残せばよい
トリガーと原因まで分かっているなら、作業はすでに80%終わっているようなものだと思う
問題になるのは、コードが完全には動いていないのに、そうであるかのように仮定するときだ
私が見た最高のTODOは、セキュリティコードに
TODO: encrypt thisと明確に残していたものだこれがあったおかげで、コードが暗号化されていないことが誰の目にもすぐ分かったし、モジュール化によって暗号化が別で処理されているのか、二重に暗号化してしまうのではないかという不安も減った
明確に誤りではあるが、それほど対処の必要性が高くない場合だ
バグとして登録するか、実際に作業するつもりがないならTODOを残さないでほしい
// TODO: If the user triple-clicks this button, the click handler errors because [xyz]
これは現象の記録にすぎない。TODOという単語は外すべきだ
FIXMEは必ず直す必要があるとき、あるいは次のステップがはっきり見えているときに使う
TODOはそれよりもう少し漠然とした考えや、頭の中から追い出して次の作業に集中するための用途だ
まだアイデアが熟していない、絶対にやるという確信がない、関連する何かを待っている、といったさまざまな状況がある
記録しないとずっと頭に残って気が散るが、TODOでも何でも書いておくだけで心理的にずっと楽になる
コメントなしでもすぐ理解できるコードを書けるなら、それが理想だ
それでも後で自分で読んでも分からないほど紛らわしいなら、やむを得ずコメントを書く
悲しいのは、その後誰かがコードを直したのにコメントを更新しないと、かえってもっと混乱することだ
TODOはコミット済みコードの中にあるべきではなく、プロジェクトやイシュー管理システムで管理されるべきだと思う