自己文書化コードとは何ですか?よく文書化されたコードを置き換えることができますか? [閉まっている]

StackOverflow https://stackoverflow.com/questions/209015

  •  03-07-2019
  •  | 
  •  

質問

自分のコードはコメントを必要とせず、「自己文書化」だと主張する同僚がいます

私は彼のコードをレビューしましたが、他の人が作成したコードよりも明確ですが、自己文書化コードがコメント付きで文書化されたコードと同様に完全で有用であることにはまだ同意しません。

彼の視点を理解してください。

  • 自己文書化コードとは
  • コメントや文書化されたコードを本当に置き換えることができますか
  • よく文書化されコメントされたコードよりも優れている状況はありますか
  • コメントなしではコードを自己文書化できない例があります

たぶんそれは私自身の制限に過ぎないかもしれませんが、それがどのように良い習慣になるかわかりません。

これは議論を意図したものではありません-コメントや文書化されたコードの優先度が高い理由を挙げないでください-これを示す多くのリソースがありますが、彼らは私の仲間を納得させません。そうでなければ、彼を説得するために彼の視点をより完全に理解する必要があると思います。必要に応じて新しい質問を開始しますが、ここで議論しないでください。

すごい迅速な対応!回答がここの他のすべての回答と大きく異なる場合を除き、新しい回答を追加するのではなく、既存の回答をすべて読んで回答にコメントを入力してください。

また、自己文書化コードに反対している皆さん-これは主に、自己文書化コードの伝道者の観点(肯定的な側面)を理解するのを助けるためです。トピックにとどまらない場合、他の人があなたに投票することを期待しています。

役に立ちましたか?

解決

私の意見では、コードはすべて自己文書化する必要があります。優れた自己文書化コードでは、すべての識別子(変数、メソッド、クラス)に明確なセマンティック名があるため、すべての行を説明する必要はありません。必要以上のコメントがあると、実際にはコードを読むのが難しくなります(!)ので、同僚の場合

  • すべてのクラス、メンバー、型、およびメソッドのドキュメンテーションコメント(Doxygen、JavaDoc、XMLコメントなど)を記述します
  • 自己文書化されていないコードの部分を明確にコメントする
  • 意図を説明する各コードブロックのコメント、またはより高い抽象化レベルでのコードの動作を記述します(つまり、すべてをループするのではなく、 10 MBを超えるすべてのファイルを見つけるディレクトリ内のファイル、ファイルサイズが10 MBより大きいかどうかをテストし、trueの場合はreturnを返します)
私の意見では、彼のコードとドキュメントは問題ありません。自己文書化されたコードは、コメントがないことを 意味せず、不必要なコメントがないことのみを意味することに注意してください。ただし、コード(コメントやドキュメンテーションコメントを含む)を読むことで、コードの機能と理由をすぐに理解できるはずです。 「自己文書化」の場合コードはコメント付きのコードよりも理解に時間がかかりますが、実際には自己文書化されていません。

他のヒント

まあ、これはコメントとコードに関するものなので、実際のコードを見てみましょう。この典型的なコードを比較してください:

float a, b, c; a=9.81; b=5; c= .5*a*(b^2);

この自己文書化コードに、何が行われているかを示します:

const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

そして、この文書化されたコードに、それが行われている理由なぜをよりよく説明しています:

/* compute displacement with Newton's equation x = vₒt + ½at² */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

そして、コメントなしのドキュメントとしてのコードの最終バージョン

float computeDisplacement(float timeInSeconds) {
    const float gravitationalForce = 9.81;
    float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);
    return displacement;
}

コメントスタイルが不適切な例:

const float a = 9.81; //gravitational force
float b = 5; //time in seconds
float c = (1/2)*a*(b^2) //multiply the time and gravity together to get displacement.

最後の例では、変数に説明的な名前を付ける必要がある場合にコメントが使用され、操作の結果が要約されます。いつでも自己文書化された2番目の例を好むでしょうし、おそらくあなたの友人が自己文書化されたコードを言うとき、それが話しているのかもしれません。

私はそれがあなたがしていることの文脈に依存していると言うでしょう。私にとっては、この場合、おそらく自己文書化されたコードで十分ですが、背後で行われていることの背後にある方法論(この例では、方程式)を詳述するコメントも有用です。

コード自体は、常にコードの機能に関する最新の説明になりますが、私の意見では、意図を説明することは非常に難しいです。これは最も重要ですコメントの側面。適切に記述されていれば、コードが何を行うかを既に知っています。なぜコードがそれを行っているかを知る必要があります!

誰かがかつて言った

  

1)理解しにくいコードに対してのみコメントを書きます。
  2)理解しにくいコードを書かないようにしてください。

「自己文書化」の背後にある考え方コードは、コード内の実際のプログラムロジックが、コードが何をしているのかだけでなく、なぜそれをしているのかをコードを読んでいる人に説明するのに十分明快であるということです。

私の意見では、真の自己文書化コードのアイデアは神話です。このコードは、何が起こっているかの背後にあるロジックを伝えることができますが、特に問題を解決する方法が複数ある場合、特定の方法でなぜ実行されているかを説明できません。その理由だけで、よくコメントされたコードを置き換えることはできません。

特定のコード行が自己文書化されているかどうかを質問することは重要だと思いますが、最終的には、コードのスライスの構造と機能を理解していないと、ほとんどの場合コメントが役に立たなくなります。たとえば、amdfanの「正しくコメント化された」スライスを見てみましょう。コード:

/* compute displacement with Newton's equation x = v0t + ½at^2 */
const float gravitationalForce = 9.81;
float timeInSeconds = 5;
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2);

このコードは問題ありませんが、以下はほとんどの最新のソフトウェアシステムで同様に有益であり、ニュートン計算を使用することは他の物理的パラダイムがより適切な場合に変更される可能性がある選択であることを明示的に認識しています:

const float accelerationDueToGravity = 9.81;
float timeInSeconds = 5;
float displacement = NewtonianPhysics.CalculateDisplacement(accelerationDueToGravity, timeInSeconds);

私自身の個人的な経験では、「普通」はほとんどありません。コメントが絶対に必要なコーディング状況。たとえば、独自のアルゴリズムをどれくらいの頻度でローリングしますか?基本的に他のすべては、コーダーが使用中の構造とそれらの特定の構造を使用するようにシステムを動かした選択を理解できるように、システムを構造化することの問題です。

これをどこから取得したか忘れましたが、

  

プログラム内のすべてのコメントは、読者にとって謝罪のようなものです。 "私のコードが非常に不透明であるため、見ただけでは理解できないのでごめんなさい"。私たちは自分が完璧ではないことを受け入れなければなりませんが、完璧になるように努力し、必要なときに謝罪を正しく行います。

自己文書化コードは、「DRY」の好例です。 (自分を繰り返さないでください)。コード自体に含まれる、または含まれる可能性のあるコメント内の情報を複製しないでください。

変数の用途を説明するのではなく、変数の名前を変更します。

短いコードスニペットの機能を説明するのではなく、メソッドに抽出して説明的な名前(コメントテキストの短縮バージョンなど)を付けます。

複雑なテストの機能を説明するのではなく、それをメソッドに抽出し、適切な名前を付けます。

その他

この後、あまり説明を必要としないコードになり、それ自体を説明するため、コード内の情報を単に繰り返すコメントを削除する必要があります。

これは、まったくコメントがないことを意味するものではなく、意図に関する情報(「理由」)など、コードに含めることができない情報がいくつかあります。理想的な場合、コードとコメントは互いに補完し合い、それぞれが他の情報を複製することなく一意の説明値を追加します。

コードの自己文書化は良い習慣であり、適切に行われれば、あまり多くのコメントを読むことなくコードの意味を簡単に伝えることができます。特に、チームの全員がドメインをよく理解している状況では。

とはいえ、コメントは新規参入者やテスター、ドキュメント/ヘルプファイルの生成に非常に役立ちます。

自己文書化コード+必要なコメントは、チーム全体の人々を支援するのに大いに役立ちます。

まず、同僚のコードが実際にあなたが見た他のコードよりも明確であると聞いてうれしいです。これは、おそらく「自己文書化」を使用していないことを意味します。コードをコメントするのが面倒だという言い訳として。

自己文書化コードは、知識のある読者が何をしているのかを理解するためにフリーテキストのコメントを必要としないコードです。たとえば、次のコードは自己文書化されています。

print "Hello, World!"

その他:

factorial n = product [1..n]

その他:

from BeautifulSoup import BeautifulSoup, Tag

def replace_a_href_with_span(soup):
    links = soup.findAll("a")
    for link in links:
        tag = Tag(soup, "span", [("class", "looksLikeLink")])
        tag.contents = link.contents
        link.replaceWith(tag)

今、「知識のある読者」というこの考えは、非常に主観的かつ状況的です。あなたや他の誰かがあなたの同僚のコードを追跡するのに苦労しているなら、彼は知識のある読者の彼の考えを再評価するためにうまくいくでしょう。コードの自己文書化を呼び出すには、使用している言語とライブラリにある程度精通している必要があります。

「自己文書化コード」を書くために私が見た最も良い議論それは、フリーテキストの解説が記述されているコードに同意しないという問題を回避することです。最高の批判は、コードはそれ自体で何をしているのかどのようにを説明できるが、何かが特定の方法で行われていることを説明できないということです。

順番:

  • 自己文書化コードは、読者に意図を明確に示すコードです。
  • 完全ではありません。コメントは、特定の戦略が選択されたなぜのコメントに常に役立ちます。ただし、コードのセクションが何をしているのかを説明するコメントは、自己文書化が不十分で、リファクタリングを使用できるコードを示しています。
  • コメントは嘘をつき、時代遅れになります。 always tells のコードは真実を伝える可能性が高い。
  • コメントなしではコードの what を十分に明確にできないケースを見たことはありません。ただし、前に言ったように、なぜについてのコメントを含めることが必要/役立つことがあります。

ただし、真に自己文書化するコードには多くの自己規律とチーム規律が必要であることに注意することが重要です。あなたはより宣言的にプログラムすることを学ばなければなりません。誰もが書いたように思えるほど明白なコードを支持するコード。

1つには、次のスニペットを検討してください:

/**
 * Sets the value of foobar.
 *
 * @foobar is the new vaue of foobar.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

この例では、コード3行ごとに5行のコメントがあります。さらに悪いことに、コードを読んでも見えないものはコメントに追加されません。このようなメソッドが10個ある場合、「コメント失明」が発生し、パターンから逸脱する1つのメソッドに気付かないことがあります。

もちろん、より良いバージョンは次のようになります。

/**
 * The serialization of the foobar object is used to synchronize the qux task.
 * The default value is unique instance, override if needed.
 */
 public void setFoobar(Object foobar) {
     this.foobar = foobar;
 }

それでも、些細なコードの場合、コメントを付けたくない。意図と全体的な組織は、コード外の別のドキュメントで説明されています。

「自己文書化コード」を読むと、 あなたはそれが何をしているのかを見る、 しかし、なぜそれが特定の方法で行われているのかを常に推測することはできません。

非プログラミングの制約がたくさんあります ビジネスロジック、セキュリティ、ユーザーの要求など。

メンテナンスを行うとき、これらのバックゴーランド情報は非常に重要になります。

ちょっと塩を......

同僚に指摘したいことの1つは、コードをどのように自己文書化しても、他の代替アプローチが考慮され、破棄された場合、その情報でコードをコメントしない限り、その情報は失われます。場合によっては、代替案が検討されたこと、そしてそれがなぜ反対されたのか、そしてコードコメントが長期にわたって生き残る可能性が最も高いことを知ることも同様に重要です。

ドナルド・クヌースの「WEB」について聞いたことがありますか?彼の Literate Programming の概念を実装するプロジェクトですか?自己文書化コード以上のものです。コードとしてコンパイルおよび実行できるドキュメントに似ています。しかし、今日どの程度使用されているのかわかりません。

違いは" what"とおよび「方法」。

  • " what"を文書化する必要がありますルーチンが行います。
  • 「方法」を文書化しないでください。特別な場合を除き、それを実行します(たとえば、特定のアルゴリズムの論文を参照)。自己文書化する必要があります。

私が働いていた会社のプログラマーの1人が、モニターの上部に次のものを貼り付けていました。

"コードを管理する人が、あなたが住んでいる場所を知っている殺人マニアのようにコードを文書化します。

コードが自己文書化されているという観点から、私は夢中になります。特定のコード行またはサブアルゴリズムは実際に自己文書化されている場合がありますが、より大きな写真での目的は単にそうではありません。

1か月か2か月前にこれにとてもイライラし、自分の視点を説明するブログ記事全体を書きました。 ここに投稿

自己文書化コードは通常、コードの実行内容と正確に一致する変数名を使用するため、何が起こっているのかを簡単に理解できます

ただし、このような「自己文書化コード」はコメントを置き換えることはありません。特に保守性の点で、コードが複雑すぎて自己文書化コードでは不十分な場合があります。

かつてこの理論を強く信じていた教授がいました 実際、彼が言ったことを覚えている中で最高のことは、「コメントは意地悪のためです」
最初は驚きましたが、理にかなっています。
ただし、コードで何が起こっているのかは理解できても、経験の浅い人が背後に来て何が起こっているのか分からない場合があります。これは、コメントが重要になるときです。私たちはそれらが重要だとは思わないことを何度も知っていますが、コメントが不要なケースはほとんどありません。

誰も" Literate Programming "をもたらしていないことに驚いています。 1981年にTeXのドナルドE.クヌースと「コンピュータプログラミングの技術」によって開発された技術。名声。

前提は単純です。コードは人間が理解する必要があり、コメントはコンパイラによって単に破棄されるため、必要なものを全員に提供しないでください-コードの意図の完全なテキスト記述。プログラミング言語の要件、人間の読者向け、コンパイラーの純粋なコード。

Literate Programmingツールは、どの部分がソースであり、テキストであるかをツールに伝えるドキュメントの特別なマークアップを提供することでこれを行います。このプログラムは、後でドキュメントからソースコード部分を取り出し、コードファイルを組み立てます。

ウェブ上で例を見つけました: http://moonflare.com/code /select/select.nw またはHTMLバージョン http://moonflare.com/ code / select / select.html

Knuthの本が図書館で見つかる場合(Donald E. Knuth、Literate Programming、Stanford、California:Center for the Study of Language and Information、1992、CSLI Lecture Notes、no。27)それ。

それは自己文書化コードであり、推論とすべてを完備しています。素敵なドキュメントを作成することも、 その他はすべてよく書かれたコメントです:-)

私の意見はこの投稿に書かれています:

への1つのヒントコードを文書化します。

抜粋:

  

多くのコメントを書く代わりに   の微妙な動作を説明する   あなたのプログラム、あなたの再構築してみませんか   自明であるように論理?   どのようなメソッドを文書化する代わりに   やっているのに、なぜ明確な名前を選ばないの   その方法のために?タグ付けする代わりに   未完成の作業を示すコード、   なぜ単に投げないのですか   NotImplementedException()?の代わりに   あなたのコメントが聞こえるかどうか心配   上司に丁寧に、   同僚やコードを読んでいる人、   なぜ心配しないで   まったく書いていますか?

     

コードが明確であればあるほど、簡単になります   それを維持し、拡張し、   将来のエディションで作業します。の   あなたのコードはあまり華やかではありません   コメントする必要があります。もっと   コメント、より高い   メンテナンス費用。

多くの有効な答えにもう1つの視点を提供したいと思います:

ソースコードとは何ですか?プログラミング言語とは?

マシンにはソースコードは必要ありません。彼らは、アセンブリを実行して満足しています。プログラミング言語は私たちの利益のためです。アセンブリを書きたくありません。何を書いているのかを理解する必要があります。プログラミングとはコードを書くことです。

書いたものを読むことができますか?

ソースコードは人間の言語で書かれていません。これは試されました(たとえば、FORTRAN)が、完全には成功していません。

ソースコードにあいまいさはありません。そのため、テキストよりも多くの構造を配置する必要があります。テキストはコンテキストでのみ機能し、テキストを使用する場合は当然のことと考えています。ソースコードのコンテキストは常に明示的です。 「使用」を考えるC#で。

ほとんどのプログラミング言語には冗長性があるため、一貫性がない場合でもコンパイラーがキャッチできます。他の言語はより多くの推論を使用し、その冗長性を排除しようとします。

タイプ名、メソッド名、変数名はコンピューターに必要ありません。それらは参照のために使用されます。コンパイラはセマンティクスを理解していません。それは私たちが使用するものです。

プログラミング言語は、人間と機械の間の言語の橋渡しです。それは私たちにとって書き込み可能であり、彼らにとって読み取り可能でなければなりません。二次的な要求は、それが私たちに読めるべきであることです。許可されているセマンティクスが得意で、コードの構造化が得意であれば、ソースコードも読みやすいはずです。最適なコードにはコメントは不要です。

しかし、すべてのプロジェクトには複雑さが潜んでおり、複雑さをどこに置くか、どのラクダを飲み込むかを常に決定する必要があります。これらはコメントを使用する場所です。

自己文書化コードは、時間の経過とともにコード、コメント、文書化が分岐するという問題を簡単にオプトアウトできます。そして、それは明確なコードを書くことを訓練する要因です(あなたがあなた自身に厳しいなら)。

私にとって、これらは私が従おうとしているルールです:

  • コードは次のように簡単かつ明確にする必要があります 可能な限り読んでください。
  • コメントには次の理由が必要です。 私が下した設計決定 このアルゴリズムを使用しますか、または 次のようなコードの制限 動作しないとき...(これは 契約/アサーションで処理 コード)(通常は関数/プロシージャ内)。
  • ドキュメントには使用法を記載する必要があります (召集を呼び出す)、側 効果、可能な戻り値。それ を使用してコードから抽出できます jDocやxmlDocなどのツール。それ したがって、通常は 関数/手順、ただしに近い それが記述するコード。

これは、コードをドキュメント化する3つの手段すべてが密接に共存しているため、コードが変更されたときに変更される可能性が高くなりますが、表現が重複しないことを意味します。

いわゆる自己文書化コードの本当の問題は、それが実際に行うことを伝えることです。いくつかのコメントは誰かがコードをよりよく理解するのに役立つかもしれませんが(例えば、アルゴリズムのステップなど)、それはある程度冗長であり、あなたがあなたのピアを説得することを疑います。

ただし、ドキュメントで本当に重要なのは、コードから直接明らかにならないものです:基本的な意図、仮定、影響、制限など

コードがXを実行していることを一目で判断できるのは、コードがYを実行していないことを判断できるよりもはるかに簡単です。彼はYを文書化する必要があります...

見栄えが良く、明らかですが、実際には入力のすべての基底をカバーしていないコードの例を見せて、彼がそれを見つけたかどうかを確認できます。

コメントの代わりに、自己文書化コードを使用するとよいと思います。コードのあり方や理由を説明するコメントが必要な場合は、より説明的なものにするために変更する必要がある関数名または変数名があります。不足分をコメントで補うか、いくつかの変数や関数の名前を変更してコードをリファクタリングするかは、コーダー次第です。

ドキュメントを実際に置き換えることはできません。ドキュメントとは、システムが物事を行う方法ではなく、システムの使用方法を説明するために他の人に与えるものだからです。

編集:私(およびおそらく他のすべての人)は、おそらくデジタル信号処理(DSP)アプリについて非常によくコメントする必要があるという規定を持つべきです。これは主に、DSPアプリが値の配列を供給し、値を加算/乗算するなどのループに対して本質的に2であるためです...プログラムを変更するには、配列の1つの値を変更します...あなたはその場合やっています;)

数学のコードを書くとき、数学、コードが使用する表記規則、およびそれらがすべてどのように適合するかを説明する、長いエッセイのようなコメントを書くことが役立つことが時々ありました。ここでは、何百行ものドキュメントを話します。

可能な限り自己文書化するようにコードを作成しようとしていますが、数か月後に再び作業するときは、説明を読んでハッシュを作成しないようにする必要があります。

もちろん、ほとんどの場合、この種の極端な測定は必要ありません。この話の教訓は、コードごとに異なる量のドキュメントが必要だと思います。一部のコードは、コメントを必要としないほど明確に記述できるため、コメントを使用せずに明確に記述してください!

しかし、多くのコードには意味をなすコメントが必要なので、できるだけ明確に記述し、必要なだけコメントを使用してください...

私は、多くの人がそうであるように、真に自己文書化するためには、コードが何らかの形の意図を示す必要があると主張します。しかし、私はまだ誰もBDDに言及していないことに驚いています-行動駆動開発。アイデアの一部は、コードの意図を説明する自動化されたテスト(コード)を持っているということです。そうでなければ、それを明らかにするのは非常に困難です。

Good domain modeling 
+ good names (variabes, methods, classes) 
+ code examples (unit tests from use cases) 
= self documenting software 

コードに加えて追加のコメントが明確になる理由はいくつかあります:

  • 見ているコードは自動的に生成されたため、コードを編集すると、次にプロジェクトがコンパイルされるときに破壊される可能性があります
  • パフォーマンスの向上(ループの展開、高価な計算用のルックアップテーブルの作成など)の代わりに、簡単ではない実装がトレードオフされました。

チームがドキュメントで重視しているのは、すべてです。方法の代わりに理由/意図を文書化することが重要であり、これは常に自己文書化コードに取り込まれるとは限りません。取得/設定これらは明らかではありませんが、計算、検索などの理由を表現する必要があります。

また、国籍が異なる場合はチームの違いに注意してください。ディクショナリの違いは、メソッドの命名にintoする可能性があります:

BisectionSearch

BinarySearch

BinaryChop

3つの異なる大陸で訓練された開発者から提供されたこれらの3つの方法は、同じことを行います。アルゴリズムを説明したコメントを読むことによってのみ、ライブラリ内の重複を特定できました。

コメントを必要とするコードを読むことは、私が知らない言語でテキストを読むことに似ています。私は声明を見て、それが何をするのか、またはなぜ理解していない-そして私はコメントを見なければならない。フレーズを読んで、その意味を理解するために辞書を調べる必要があります。

通常、実行内容を自己文書化するコードを書くのは簡単です。その理由を説明するには、コメントの方が適していますが、ここでもコードの方が適しています。抽象化のすべてのレベルでシステムを理解している場合、次のようにコードを整理してみてください

public Result whatYouWantToDo(){
  howYouDoItStep1();
  howYouDoItStep2();
  return resultOfWhatYouHavDone;
}

メソッド名があなたの意図を反映し、メソッド本体があなたの目標を達成する方法を説明します。 とにかく本のタイトル全体を伝えることはできないため、システムの主要な抽象化、および複雑なアルゴリズム、重要なメソッドコントラクト、アーティファクトを文書化する必要があります。

同僚が作成したコードが本当に自己文書化されている場合-あなたと彼は幸運です。 同僚のコードにコメントが必要だと思われる場合は、コメントが必要です。その中で最も重要な場所を開いて、一度読んで、すべてを理解しているかどうかを確認してください。コードが自己文書化されている場合-する必要があります。そうでない場合-同僚に答えを出した後、同僚に事前にコメントやコードに文書化されていない理由を尋ねます。彼はコードは彼のような賢い人のための自己文書であると主張することができますが、彼はとにかく他のチームメンバーを尊重する必要があります-あなたのタスクが彼のコードの理解を必要とし、彼のコードがあなたに理解する必要があるすべてを説明しない場合-それは必要コメント。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top