増えすぎたTODOコメントは撲滅しなければならない


この記事はClassi Advent Calendar 2019 12日目の記事になります。
Classiでバックエンドなどをやっています、@Seigaと申します。アドベントカレンダーに参加するのは初めてなのですがどうぞよろしくお願いいたします。

弊社には整地部という有志による活動があり、モブプロ形式でリファクタリングやパフォーマンス改善などをやっています。ちなみに整地部と名乗り始めた元祖らしい。

その整地部活動の1つとしてやっているのがTODOコメント撲滅運動です。
この記事ではなぜ撲滅していくのか、どうやって撲滅していくのかといったことについて解説していきます。

なぜTODOコメントを撲滅するのか

TODOコメントの漬物化現象


燦然と輝くTODO「実装」コメント(3年もの)

そもそもTODOコメントとはどういうものでしょうか?
だいたい上記のようなものです
まあここまで酷くなくても、

# TODO: メソッド名を適切なものに変更する

とか

// TODO: モジュール化する

のようなTODOコメントを見かけた(or作った)ことはあると思います。TODOコメント文自体の出来不出来はこの際問題ではありません。問題なのはそれらのTODOコメントは役割を全うし、すぐに解消されているかどうかです。

私たちは整地部の合宿にて4つのリポジトリで合計370個のTODOコメントを見つけ、そのほどんどが1年以上前のものでした。TODOとされたあと、誰にも触られず、忘れ去られ...

コードは漬物TODOコメントの墓場と化していました

上記画像もその1つで実際にあったTODOコメントです。カナシイ...カナシイ...。
ある調査では、GitHubの全.NET系リポジトリを対象にTODOコメントがどれくらい放置されてしまうのかを集計した所、現在あるTODOコメントの62.3%は1年以上前のものらしいです。1

なぜ、TODOコメントは放置されがちになってしまうのでしょうか?
その理解にはTODOリストの問題点を知るのが近道でしょう。

TODOリストの5つの問題点

To-Do Lists Don’t Workというハーバードビジネスレビューの記事があるのですが、その中ではTODOリストがなぜ機能不全に陥るのかを以下の5つの問題点から述べています。

  1. 選択のパラドックス
    人は多すぎる選択肢から1つを選ぶことに大きな負担を感じるという研究結果がある。
    58個のTODOがある時、それらを1つ1つ消化するよりも、1時間メールをチェックすることを選択する。

  2. 不均一の複雑さ
    リストに3分の長さのタスクと33分の長さのタスクが含まれている場合、タスクを完了した時に生じる心理的な見返りとドーパミン放出のために、常に短いタスクに集中してしまう

  3. 不均一の優先順位
    TODOリスト内で暗黙的に優先度づけをし、優先度の低いものは最優先に昇格するまで放置されてしまう。明確なメカニズムに基づいた優先度づけではないので、実は非常に重要なTODOであったとしても判別できない

  4. コンテキストの欠如
    TODOリストは、作業内容を決定するのに役立つタスクのコンテキストを提供しない
    なぜやるのか、どのようにやればいいのか、何をもって完了とすべきなのか。この問題はTODOリスト作成からしばらく時間が立った後に再び着手しようとした際に顕著になる。このタスクを完了させるためのコンテキストをまるっきり忘れているのだから!

  5. コミットメントデバイスの欠如
    最も重要な(大抵最も難しい)タスクに強制的に着手させるような力学が欠如しているので、楽なタスクを選択することを防げない。いわゆる背水の陣システム。

要するにTODOリストそのものが、TODOの完了自体にはにまるで無頓着ということが問題視されていました。2
同じことがTODOコメントにも言えるのではないでしょうか?

TODOコメントそのものはTODOコメントの完了にまるで無頓着

TODOコメントが提供する情報は、対応するコードの開始行と、このTODOコメントを残した人が、その瞬間こうすべきだと思ったという思考の残滓だけ...。
強制力もなく、どういう優先度で、どのように、どうして、誰が、いつまでにやるのか、といった様々な必要情報と紐づいていない状態です。故に自然と放置されるTODOが増え、いつの間にか漬物TODOの墓場と化すのです。
TODOコメントは技術的負債を示すマーカーです。解消のために力を尽くさないとアプリケーションの負債が溜まっていってしまいます。

よって思ったわけです。

増えすぎたTODOコメントは撲滅しなければならない

と...。

どうやってTODOコメントを撲滅するのか

そもそもTODOコメントの存在意義とは何でしょう?
Uncle BobのClean CodeにはTODOコメントについて以下のように述べています。

TODOとは、プログラマーがやるべきだと思う仕事ですが何らかの理由で現時点ではできないものです。廃止された機能を削除することを思い出させるか、誰かが問題を見るように懇願するかもしれません。他の誰かがより良い名前を考えたり、計画されたイベントに依存する変更を行うように思い出させるためのリクエストかもしれません。それらのTODOが何であれ、システムに悪いコードを残すことの言い訳にはなりませんが。3

まとめるとTODOコメントの使い道として次のようなものがあります

  • 作業リソース的に後回しにせざるを得ないタスク
  • 何らかの変更に付随して対応してほしいタスク
  • 未来の自分や他の誰かに、より良いコードにしてもらうのを期待する目印

ではこれらの要件はTODOコメントでなければ満たせないものでしょうか?
いいえ、現代では様々なツールや手法の登場により、TODOコメントに頼らずに要件を満たすことが可能になっています。以下にいくつか方法を紹介します。

TODOコメントは適切なトラッキングツールに移行

既存のTODOコメントは削除してしまい、GitHub IssueやAsana、JIRAなど適切なタスクトラッキングツールに移行してしまいましょう。ただのTODOコメントよりもずっと多機能で、解決にフォーカスしています。新しく書きたくなった場合もそっちです。

こうすることでトラッキングツール上でのコメントなどを通し適切なディスカッションをすることができます。検討の結果、優先度や担当者、期限の決定ができるはずです。また、詳細なコンテキストの共有をすることで、なぜやるのか、どのようにやればいいのか、何をもって完了とすべきなのか、といったTODOコメントだけでは分かり得ないコンテキストの明確化をすることができます。

GitHub IssueにTODOタグをつけて書いた例

この際に3年前など古いTODOで、コンテキストが失われていたり意図がわからないものについては、時間をかけて考古学するより消してしまった方が良い場合の方が多いです。必要になれば要件として勝手に再浮上してくれます。

TODOコメントをmasterにマージさせない

TODOコメントを書くのは手軽です。なので個人の作業用ブランチ上ではいくらでもTODOコメントを書き込んでしまっても良いと思います。それらTODOコメントは新鮮なので、コンテキストも自分の中にあり、その場で解決する分には難しくないはずです。

ただし、masterにマージされる前に絶対にTODOコメントを解決する強い仕組みが必要です。例えば、GitHubアプリのCheck TODOはプルリクコードにTODOコメントが含まれている場合GitHub Checksを落としてくれます。


TODOコメントを削除するとCheckが通るようになる

このようにして強制的にTODOを解消させる(またはIssueなどに移行させる)仕組みを用意することができます。

変更を検知することでTODOを腐らせない

変更を検知して強制的にTODOを解決させる、という手法もあります。
次のようなTODOコメントを書きたくなったとしましょう。

# TODO: Railsのバージョンが6.0以上になったら本体のBulk insertに置き換える

このように「タスクを後回しにするタイプのTODO」ではなく「何らかの変更に付随して対応してほしいタイプのTODO」は工夫が必要になります。
すぐ解決できるタイプではないので、トラッキングツールに置いても放置されがちなタスクとなってしまい、結果的に見逃される可能性があるからです。
どのようにすれば良いでしょうか?

この場合、テストコード中に変更を検知してエラーをRaiseするコードを書きましょう。対応するトラッキングツールへのリンクも添えます。

if Gem::Version.new(Rails.version) >= Gem::Version.new(6)
  raise 'Railsのバージョンが6.0以上になったら本体のBulk insertに置き換える'\
        'Issue: https://~'
end

このように変化の検知さえ仕込めれば、見逃されることなく適切なタイミングでTODOの解消ができます。

まとめ

かつてGitHub IssueやAsanaもなかった古の時代。コード上の課題を共有する方法として、コード上に直接タスクを書いて共有する手法が流行るのはごく自然な流れでした。課題の場所が分かりやすいですし、何より簡単です。

しかし現在では様々なツールの登場により、そうした要件をTODOコメントを使わずに満たすのはずっと簡単になりました。それらに頼っていけば、きっと撲滅できるはずです。弊社整地部の撲滅活動もまだ道半ば。眠っているTODOコメントはまだまだ多いので、強い意志でやっていきたいものです。

良い撲滅ライフを!

次回は@shio312さんです。

参考文献

http://wiki.c2.com/?TodoComments
https://dev.to/razbakov/todo-in-code-b
https://dev.to/forstmeier/stop-committing-todos
https://softwareengineering.stackexchange.com/questions/125320/do-todo-comments-make-sense


  1. https://dev.to/petermorlion/the-lifetime-of-todo-comments-the-results-503o 

  2. 最終的にこの記事ではTODOに入れるのをやめてGoogleカレンダーなどに登録していくことを勧めていました。まあ7年前の記事なので、Todoistなど便利なTODOトラッカーツールを上手く使えば上記の問題点はいい感じに解決できると思います。 

  3. 「Clean Code-A Handbook of Agile Software Craftsmanship」 P65 4章 Commentsより翻訳