tonocchoのメモ

軽い気持ちで

コメントのいらないプログラムについてちょっと考えた

www.hassy-blog.com

はっしーさんはクライストチャーチでプログラマをされている方で別にコメント書いたら殺すマンというよりは今の環境がコメントを書かない文化になっているようで、コメントを書かない文何か他のもので担保しているような気はするのだけど、コメントについてちょっと書いてみようかと思います。すいませんがリーダブルコードとか読んだことないです。

まずアジャイルにおいてコメントは、というかドキュメンテーションは

アジャイル宣言では「動かないドキュメントより動くコードが大事だよね」というのがあって、ドキュメントに割くコストとコーディングに割くコストを天秤にかければ後者ですよね、というのがポイントです。なので、一時期流行った「語るコード」とか、「コードが設計書」という流れができたような気がします。

とはいえ自分の立場としては「コメントは必要」という立場ですが、「不要なコメント書くくらいならコード書いたほうがいい」という点や「ときとともにコードと乖離していくならむしろコメントは害悪」という立場でもあります。また「書いたコードはたしかに語っているけどハナモゲラ語じゃワカンネーからコメント書いとけ、な?」という人でもあります。

コメントを書く場合はどういうときか

さて、以前Log4Jのソースを追っかけてたとき(どんだけ前だよ)に以下のコメントがありました。

// Make Windows Happy

コレをやらないとWindowsで痛い目見るということのようで、このような環境に依存することは「なんでわざわざやってんの」ということを書く必要があると思います。

で、コレについては別にいいというか書くべきコメントなのですが、もう一点あるのは「契約書としてのコメント」です。DbCですね。

コメントが契約とは?

JavaではJavaDocを書く、ということがあります。最近の他の言語でもだいたいこの仕組みあると思いますが、なんでこういう機能があるかというと「これから書くコードはxxを満たすよ」ということの契約書(仕様書)を書いているわけです。

ということはJavaDocに対してテストを書いたり実装を書くという感覚が実は正しい気がしますね。仕様に対してコードをかけ、というアレです。

なんでコードに対してテストを書くのがうーん、かというと、「実装に対してテストを書けば実装を通すテストを書いてしまう」からです。TDDの世界ではまずテストを書く、というのが大事だけど、それより前に「これから書くコードは何をするの?」を明確にしなくてはなりません。で、この「明確にした何か」というのが仕様(コメント)でしょう。

もうちょっというと、仕様(コメント)がないなら「ソースを書いてテストも書いてカバレッジ100%、全ケース正常終了」というシチュエーションができたとしても、「その作ったものがそもそも正しいかの担保」をどこでするか、という問題が出てくると思います。

契約としてコメントを書くと変わることがある

例えばですが

// 2つの変数を足して代入する int sum = x + y;

というコメントは無意味です、というかコメントなしでもコレはわかってほしいところです。ですが以下のコードの場合はどうでしょうか。

public int add(int x, int y){ if ( x < y ) { throw new IllegalArgumentException("x < y");

ここでアプローチは2つあると思います。1つめはコメントを書かない方でifブロックをわかりやすい名前のメソッドで置き換える、2つ目はJavaDocかソース内のコメントにしっかりと書いておく。

1つ目のアプローチを採用するときの事情としては

  • 内部の開発者はみんなコードを見ることができるし、なぜそうするかの理由は別のドキュメントにすでに書かれている
  • 外部の開発者にはなんでIAEを投げるのかは何らかの事情で知ってほしくない、または別に外部に公開するものではない

ということかと思います。コードがシンプルすぎて混乱するかもですがそのへんは置いとくとしよう。

2つ目のアプローチは、APIの仕様をきちんと公開してブラックボックスとして使ってほしい場合かと思います。いちいち実装見なくてもコメント見れば全部書いてあるよ、という立場を取る、ということですね。また、書いてあることはすべてテスト済みであるということにもなるし、もし書いてあることと挙動が違えば誰が見てもバグとしてレポートできます。

この辺は結構主観的に「こういうことかな」くらいで書いてありますが、そのコード自体に対するステークホルダーが誰、という点次第でコメントを書く是非や書く場所というのも変わってくると思います。

コメントとコードとテストのアレなアレ

ちょっとしたポイントとしてでなく、仕様としてコメントをソース内に書いてしまうと、コメントのメンテを誰がやるの、という問題が出てきます。仕様を書く人が必ずしもソースコードを編集するとは限りません。むしろWikiとかに書いておいて仕様の記述内容を変える副作用を抑えるという方策を取る場合もあるかもしれません。または、きちんとしたライターにコメントを書いてもらうところもあるかもしれません。

そう考えるとプログラマがコメントを書く、という作業が必須かどうかというポイントはありそうです。

例えば依存するライブラリやサーバーのバグに対するワークアラウンドなんかはソースに書いてあったほうが便利だなとは思いますが。

あとは、テスターがやるテスト(結合テスト)で出たバグがすべて、という環境でもまたコメントの扱いは変わりそうです。

そういうわけで、コメントは必須だろうという人も多いかと思いますが、「どういうコメントがどういう扱いをされるべきか」というのは議論があっても楽しそうですね。