web-dev-qa-db-ja.com

清潔さのために1行のコードに関するコメントを避ける方法

私はいくつかのベストプラクティスを使用してコードの一部をクリーンアップしようとしています。コメントは、ほとんどの場合、将来の保守性にとって悪い考えです。適切な名前のメソッドにリファクタリングすることで、それらのほとんどを取り除くことができました。

ただし、コードが1行だけ存在する必要がある理由を説明するコメントが散りばめられています。これらを取り除く方法を理解するのに苦労しています。彼らはしばしばこの種の構造に従います:

_// Needs to start disabled to avoid artifacts the first frame. Will enable after frame complete.
lineRenderer.enabled = false;
_

その後、後でコードで有効にします。

StartLineRendererDisabledToAvoidArtifactsFirstFrame()と呼ばれる1行のメソッドにそれを抽出することを考えましたが、これは私にはそれほどきれいに見えません。

そのようなワンライナーを扱うためのベストプラクティスはありますか?それらの多くは、表面上は不必要に見えても実際には重要な機能を持つコードの存在を説明しています。今後削除されないようにしたい。

補足:リファクタリング/名前変更によってこれらのコメントが古くなったり、間違った場所に置かれたりするようなシナリオにすでに遭遇したので、コメントを削除することがなぜ有用であるのかを明確に理解しています。

ここに関連するが異なる質問:

以下の回答とコメントに基づいて編集する

以下は、以下のすばらしいディスカッションからの私のテイクアウトです。

  1. より明確にするためにリファクタリング/名前変更を簡単に行う方法がなければ、コメントは問題ありません。しかし、それらは慎重に使用する必要があります。
  2. コメントを削除することは一般的に良いことです。しかし、将来の読者が深く掘り下げることなくコードを理解できるように、コメントがいくつか存在する必要があります。
  3. しかし、彼らは方法ではなく、理由を説明するべきです。
  4. 非常に重要な特定の理由でコードが存在する場合、またはバグを修正する場合は、それに対応するユニットテストもあるはずです。
  5. コミットメッセージは、コメントされたコードが発生した理由、場所、方法を追跡するのに役立ちます。
65
Adam B

ここではまだ見たことのない提案です。私は通常、多くのコメントなしで最初のコードを記述しますが、理解しにくいコードに出くわした場合、コードを再検討/再読する理由があるたびに(通常、最初にコードを書いているときに数回行います)それをリファクタリングするか、コメントを追加するか、コメントを改善します。理解するために次回ここに立ち寄る必要がないようにするために必要なことは何でも。コードを書くことは他のクリエイティブなプロセスと同じです。ドラフトを作成し、いくつかのテストを行い、それを機能させ、クリーンアップし、理解できるようにする必要があります。これらの各アクティビティは、戻ってきて、すでに行った内容を再確認します。それは反復的であり、その反復的プロセスの一部は、それを理解することが可能な限り簡単であることを確認することです。

ただし、考慮すべき問題が1つあります。ほとんどのプログラマは、コメントを読んでも十分に信頼できないからです。よくコメントして注意を払うと、コメントで既に明確に回答されている質問が表示されることがわかります。私はこれに対処する方法がわからないので、私は自分のためにコメントを書き、彼らが私のコードについて質問するとき、私が何をしたか覚えていなくても、答えはコメントのすぐそこにあると信じています。調べて答えてください。

0
Bill K

多くの人が言ったように、whatではなくwhyを説明するコメントは、一般的に良い考えです。あなたの例は、明白でないコードが存在する理由を説明するコメントの完璧な例です。

この正確なコード行とコメントのコピーが複数の場所にある場合、繰り返しを避けるために1行の関数を作成することは理にかなっています。

この1行が周囲のコードと同じ概念レベルにない場合は、分離することもできます。たとえば、このフラグを反転する前後のステートメントが非常に高レベルの概念である場合、コメントでそれを説明する必要性は、誤った抽象化レベルで機能する兆候である可能性があります。

この架空のコンテキストを検討してください:

CommitRenderingContext(blah, blah, blah);
PrecalculateLookUpTable(parameters);

// Needs to start disabled to avoid artifacts the first frame. Will enable after frame complete.
lineRenderer.enabled = false;

lineRenderer.RenderFrames(frame_count);

ワンライナーが説明を必要とする付近での唯一の声明であるという事実は、その周りで行われているより高いレベルの作業の文脈ではそれが場違いであることの手がかりです。おそらく、lineRendererはループ非表示インデックスRenderFrames内で有効になります。つまり、このフラグをいじる2つの場所は、距離だけでなく概念レベルでも分離されます。その場合、それはおそらくRenderFramesメソッド内に属し、コメントはそこで非常に適切です。

一方、コンテキストが次のようなものである場合:

lineRenderer.color = user_selected_color;

// We use half the desired thickness because we're going to do two passes.
lineRenderer.thickness = user_selected_thickness / 2;

// Needs to start disabled to avoid artifacts the first frame. Will enable after frame complete.
lineRenderer.enabled = false;

for (int i = 0; i < frame_count; ++i) {
    ... detailed calculations ...
    if (lineRenderer.enabled) {
        ... do something with lineRenderer ...
    } else {
        lineRenderer.enabled = true;
    }
}

それから私はコメントを場違いとは考えません。

0
Adrian McCarthy