あなたのコードにコメントを書くことについてのアドバイスや経験をあなたから聞きたいです。最も簡単で有益な方法でそれらをどのように記述しますか?コードの一部をコメントするとき、どのような習慣がありますか?多分いくつかのエキゾチックな推奨事項?
この質問がコメントのための最も興味深いアドバイスと推奨事項を集めてくれることを願っています。
はい、始めます。
通常、多くの行にコメントを付ける必要がある場合でも、/* */
コメントは使用しません。
利点:このような構文を1行のコメントと混在させる場合よりも、コードは視覚的によく見えます。ほとんどのIDEには、選択したテキストにコメントを付ける機能があり、通常は1行の構文でコメントを付けます。
短所:IDEなしでそのようなコードを編集するのは難しい。
完成したコメントの最後に「ドット」を配置します。
例えば:
//Recognize wallpaper style. Here I wanted to add additional details
int style = int.Parse(styleValue);
//Apply style to image.
Apply(style);
アドバンテージ:終了したコメントにのみ「ドット」を配置します。時々あなたは時間的な情報を書くことができるので、「ドット」の欠如はあなたが戻ってこのコメントにいくつかの追加のテキストを追加したかったことを伝えます。
列挙、コメントパラメータなどのテキストを揃えます。
例えば:
public enum WallpaperStyle
{
Fill = 100, //WallpaperStyle = "10"; TileWallpaper = "0".
SizeToFit = 60, //WallpaperStyle = "6"; TileWallpaper = "0".
Stretch = 20, //WallpaperStyle = "2"; TileWallpaper = "0".
Tile = 1, //WallpaperStyle = "0"; TileWallpaper = "1".
Center = 0 //WallpaperStyle = "0"; TileWallpaper = "0".
};
アドバンテージ:見た目が良く、視覚的にも簡単で、必要なものを見つけることができます。
短所:調整に時間がかかり、編集が難しくなります。
コードを分析しても得られないコメントをテキストで記述します。
たとえば、愚かなコメント:
//Apply style.
Apply(style);
Advantages:コメントに役立つ情報のみが記載された明確で小さなコードが作成されます。
以下のステートメントのいくつかは、かなり正当化されていますが、かなり個人的なものであり、このように意図されています。
簡単なバージョンについて...私はコメントを使用します:
詳細と(おそらくあいまいな)理由については、以下をお読みください。
言語に応じて、単一行コメントまたは複数行コメントを使用します。なぜそれが依存するのですか?それは単なる標準化の問題です。 Cコードを作成するときは、デフォルトで旧式のANSI C89コードを使用するので、常に/* comments */
を使用することを好みます。
したがって、ほとんどの場合Cでこれを使用し、Cのような構文を持つ言語の場合は(コードベースのスタイルに依存する)場合があります。
typedef struct STRUCT_NAME {
int fieldA; /* aligned trailing comment */
int fieldBWithLongerName; /* aligned trailing comment */
} TYPE_NAME;
Emacsは素晴らしいですし、M-;
を使って私のためにそれを行います。
言語が単一行コメントをサポートし、Cベースではない場合、単一行コメントを使用するように強く求められます。それ以外の場合、私は今、その習慣を身に付けていると思います。それは私を簡潔にすることを強制するので、それは必ずしも悪いことではありません。
このため、1行コメントを使用する方が視覚的に魅力的です。私はこれを使います:
/*
* this is a multi-line comment, which needs to be used
* for explanations, and preferably be OUTSIDE the a
* function's or class' and provide information to developers
* that would not belong to a generated API documentation.
*/
またはこれ(ただし、個人のコードベースまたはほとんどの場合は著作権表示を除いて、これ以上頻繁に使用することはありません。これは私にとって歴史的なものであり、私の学歴に由来します。残念ながら、ほとんどのIDEはそれを台無しにしています自動フォーマットを使用する場合):
/*
** this is another multi-line comment, which needs to be used
** for explanations, and preferably be OUTSIDE the a
** function's or class' and provide information to developers
** that would not belong to a generated API documentation.
*/
本当に必要な場合は、後のコメントで前に述べたものを使用してインラインでコメントします。たとえば、非常に特殊な戻りの場合、またはswitch
のcase
ステートメントをドキュメント化する場合(まれに、スイッチを頻繁に使用しない)、またはif ... else
制御フローでブランチをドキュメント化する場合。それがこれらのいずれでもない場合は、通常、関数/メソッド/ブロックのステップの概要を説明するスコープ外のコメントブロックが私にとってより意味があります。
私はこれらを非常に例外的に使用していますが、ドキュメンテーションコメントをサポートしない言語でコーディングする場合を除きます(以下を参照)。その場合、それらはより一般的になります。しかし、一般的なケースでは、それは本当に他の開発者のために意図されているものを文書化するためのものであり、本当に目立つ必要がある内部コメントです。たとえば、「強制」_catch
ブロックのような必須の空のブロックを文書化するには、次のようにします。
try {
/* you'd have real code here, not this comment */
} catch (AwaitedException e) {
/*
* Nothing to do here. We default to a previously set value.
*/
}
これは私にとってすでに醜いことですが、状況によっては許容できるでしょう。
Javadocなど.
私は通常、それらをメソッドとクラスで使用して、機能を紹介する(または変更する)バージョンを文書化し、特にそれがパブリックAPIの場合は、いくつかの例(明確な入力と出力のケース、および特別なケース)を提供します。場合によっては、ユニットケースでこれらを文書化した方がよい場合もありますが、ユニットテストは必ずしも人間が読めるとは限りません(使用するDSLに関係なく)。
すべてのドキュメント生成フレームワークが後続のドキュメントコメントをサポートしているわけではないので、これについての後続のコメントを好むので、フィールド/プロパティのドキュメントに少しバグがあります。たとえば、Doxygenにはありますが、JavaDocにはありません。つまり、すべてのフィールドにトップコメントが必要です。ただし、Java行はほとんどの場合比較的長いので、私はそれを乗り切ることができます。そのため、後続のコメントは、許容範囲のしきい値を超えて行を延長することによって、同様に私を忍び込ませます。Javadocがそれを改善すると、私はもっと幸せになるでしょう。
Cライクな言語(厳密なCでコンパイルする場合を除いて、実際には使用しない)で1つの理由だけで1行を使用します。コーディング中にコメントアウトするためです。ほとんどのIDEには、単一行コメント(インデントまたは列0に配置)のトグルがあり、それは私にとってそのユースケースに適合します。複数行のコメントのトグルを使用すると(または一部のIDEの場合は行の途中で選択すると)、コメントとコメント解除を簡単に切り替えることが難しくなります。
しかし、SCMのコメントアウトされたコードに反対しているため、コメントアウトされたチャンクをコミットする前に削除するので、通常は非常に短命です。 (- my answer この質問への "edited-by in lineコメントとSCMs" )を読んでください
私は通常書く傾向があります:
この ドナルド・クヌースによる論文 で紹介されているように、 文芸的プログラミング に興味を持ちたいと思うかもしれません。
文芸的プログラミングパラダイム、[...]は、コンピューターによって課される方法と順序でプログラムを書くことから離れる動きを表し、代わりにプログラマーが論理と思考の流れによって要求される順序でプログラムを開発できるようにします。 2 文芸プログラムは、エッセイのテキストのように、通常の人間の言語で論理の途切れのない説明として書かれています[...]。
文芸的プログラミングツールは、文芸的ソースファイルから2つの表現を取得するために使用されます。1つはコンピューターによるさらなるコンパイルまたは実行に適した「もつれた」コードで、もう1つはフォーマットされたドキュメントとして表示するためのものです。文芸的出典。
補足と例として: nderscore.js JavaScriptフレームワークは、私のコメントスタイルに準拠していないにもかかわらず、よく説明されたドキュメントのかなり良い例です コードベース と整形式 注釈付きソース -APIリファレンスとして使用するのは最善ではないかもしれません)。
これらは個人規則です。はい、私は奇妙かもしれません(そしてあなたもそうかもしれません)。あなたがチームのコード規約を遵守し、遵守する仲間と作業するとき、または彼らの好みを根本的に攻撃しない限りcohabitateうまくいっていれば問題ありません。それはあなたのスタイルの一部であり、あなたはコーダーとしてあなたを定義するコーディングスタイルの開発(またはあなたが関係している思想や組織のフォロワーとして)の間に細かい境界線を見つけるはずです。および一貫性に関するグループの規則を尊重する。
私が大学に行ったとき、私は常にすべてのコード行とすべてのメソッドヘッダーにコメントするように教えられました。それは、あなたが疑いなくそれをやるほどまでに/教え込まれていました。さまざまな会社のいくつかのアジャイル開発チームに参加していたので、ブルームーンに一度コメントを書くことができます。
この理由は2つあります。最初に、101の異なることを行う長いモノリシックメソッドを作成する必要はなくなります。クラス、メソッド、変数の名前は自己文書化する必要があります。次のログイン方法を例にとります。
public void Login(string username, string password)
{
// Get the user entity
var user = userRepository.GetUser(username);
// Check that the user exists
if (user == null)
{
throw new UserNotFoundException();
}
// Check that the users password matched
if (user.HashedPassword != GetPasswordHash(password))
{
throw new InvalidUsernamePasswordException();
}
//Check that the users account has not expired
if (user.Expired)
{
throw new UserExpiredException();
}
//Mark user as logged in
...
}
これは、はるかに読みやすく、おそらく再利用可能なものに書き直すことができます。
public void Login(string username, string password)
{
var user = GetUserForUsername(username);
CheckUsersPasswordMatched(user, password);
CheckUserAccountNotExpired(user);
MarkUserAsLoggedIn(user);
}
private void User GetUserForUsername(string username)
{
var user = userRepository.GetUser(username);
if (user == null)
{
throw new UserNotFoundException();
}
return user;
}
private void CheckUsersPasswordMatched(User user, string password)
{
if (user.HashedPassword != GetPasswordHash(password))
{
throw new InvalidUsernamePasswordException();
}
}
private void CheckUserAccountNotExpired(User user)
{
if (user.Expired)
{
throw new UserExpiredException();
}
}
あなたは何が起こっているのかをログインメソッドからはっきりと見ることができます。これは余分な作業と見なされる場合がありますが、メソッドは小さく、ジョブは1つしかありません。さらに、メソッド名はわかりやすいので、メソッドヘッダーのコメントを記述する必要はありません。メソッドが多すぎる場合は、関連するメソッドをUserAuthenticationServiceなどの別のオブジェクトにリファクタリングする必要があることを示しています。オブジェクトには1つのジョブのみが含まれている必要があります。
次に、コメントを含め、作成するコードのすべての部分を維持する必要があります。コメントが多いほど、維持する必要があります。クラスまたは変数の名前を変更すると、コンパイルエラーが発生しますが、コードのセクションの動作方法を変更するか、コードを削除して、関連するコメントを更新しないと、コンパイルエラーは発生せず、コメントがハングして混乱を引き起こします。 。
APIを作成している場合、パブリック向けのインターフェイス、クラス、列挙には、ドキュメントのヘッダーコメントが適切に記述されているはずです。
フォーマットよりもコンテンツに重点を置きます。たとえば、あなたの例のコメントは何も新しいことを教えてくれません。彼らはコードを読むことを損なうので、それらは価値がないよりも悪いです、そしてこれらのようなコメントはせいぜい元のプログラマーが彼がそれを書いた時に彼がやっていたと思っていたことへの漠然とした参照です。コード例から、スタイルapply(Style)
を適用していることがわかります。ソースを読み取ることができます。私はあなたの心を読むことができません-なぜあなたはそれをしているのですか?.
例えば。のではなく
//Apply style.
Apply(style);
する必要があります
// Unlike the others, this image needs to be drawn in the user-requested style
apply(style);
私たちのほとんどは、既存のコードを使ってチームで作業し、チームの他のメンバーが行う方法、すでに行われている方法でフォーマットします。かなりよりもはるかに重要な一貫性。
できる限り、コメントが完全に無関係になるようにコードを記述してください。重要な概念が明らかになるような方法でコードを記述できない場合にのみ、コメントを追加します。
私の好みは、それを本当にシンプルに保つことです。私はあらゆる種類の派手なフォーマットを避けています。これの主な理由は、ソースコードは最も単純なテキストエディターでも快適に編集できる必要があるためです。また、テキストの段落をハードラップすることはありませんが、代わりにエディターにソフトラップを行わせます(改行を追加しません)。
私はよくそのようなコメントを目にします、そしていくつかのツールはそれをそのように自動的に生成します:
/**
* This is an example, how to waste vertical space,
* and how to use useless asterixes.
*/
2行少ない:
/** This is an example, how to spare vertical space,
and how to avoid useless asterixes. */
IDEとエディターは、メモ帳レベルより少し上にあり、コメントを検出して別の色で印刷できます。行の先頭をアスタリスクで装飾する必要はありません。
インデントにタブを使用すると、バイト数を節約できます。
コメントを灰色のトーンで表示する高度なエディターを使用しない場合、大量のアスタリスクが強調されて注目を集めます。これは、正しいこととは逆に、背後にとどまることです。
最も重要な推奨事項は次のとおりです。
明白ではなく、予想外のコメント!
このようなコメントは役に立たない:
// Adds a to b and write the result to c
c = a + b;
それはコードが言っていることを繰り返すだけであり、コードを理解していない人はコードを理解していない、コードを読み取っていない、コードを読み取っていない場合はコメントを書いてはいけません。コメントも読まない。コメントは主に、コードを理解できる程度に理解できる他の人のために書くことに注意してください。
したがって、ほとんどのコードはコメントをまったく必要としないはずです。なぜなら、コードのほとんどが不器用で、コメントなしでは理解できない場合、コードまたはコーディングスタイルに問題があるためです。コメントはルールではなく例外である必要があります。つまり、コメントのスタイルはコードスタイルほど重要ではありません。
コードにコメントを配置して不明瞭でないものにコメントを付ける場合は、単純で短く、要点を簡潔にすることをお勧めします。そのような種類の表彰は、文法的に正しい文である必要も、句読点を使用する必要もありません。それらはコンパイラーだけでなく人間にとっての追加コードのようなものです。
// Setting owners must happen on main thread
// and this function must not block
if (!info->owner) return errMissingOwner;
いいコメントはどうですか?コードを読んだばかりのプログラマは、「所有者がいない場合、エラーを返すのではなく設定するだけではどうでしょうか?」というコメントが答えになります:メインスレッドで発生する必要があり、このステートメントだけで、関数がメインスレッドで実行されていない可能性があることを意味します。さて、しかしプログラマは「なぜメインスレッドにディスパッチしないのか?」と疑問に思うかもしれません、そしてコメントは答えを与えます:関数はブロックしてはならず、あなたはできませんメインスレッドが現在何を行っているかを確実に知らない限り、ブロックされないことを保証します。したがって、コメントはコードだけでは答えられないすべての質問に答え、これらの答えはどれも明白ではありません。コメントのおかげで、読者はエラーで失敗することがここで唯一の意味のあるオプションである理由を知っているでしょう、そしてそれはまた、愚かな間違いをしないようにコードに触れたいと思う将来のプログラマーを助けるでしょう。
しかし、本当に重要なコメントは、文書化を目的としたコメントです。誰かがあなたのインターフェースだけを知っていて実装を知らない場合、コメントはあなたのコードを正しく使う方法とどのような振る舞いを期待するかに関する唯一の追加情報源です。これらのコメントは読みやすく、通常は文全体であり、正しい文法と句読点を使用する必要があります。
/// Sorts an integer array in place.
/// The sorting algorithm is stable.
/// Sorting takes O(n * log2(n)) time
/// and at most (n / 4) * sizeof(int) memory.
///
/// @param array The array to be sorted.
/// @param count Number of elements in the array.
///
/// @return @c false if memory allocation failed and
/// the array wasn't touched, @c true otherwise.
///
bool sortIntArray ( int * array, size_t count );
そのコメントがなければ、プログラマーは関数が何をするか、パラメーターが何を意味するかを推測するかもしれませんが、ソートが安定しているかどうか、時間またはメモリの境界、または操作が失敗する理由と正確な理由を知ることは不可能です。失敗の結果はなります。
ここに私が私の仕事のコード全体で見つけた「アンチパターン」があります:「変更ログ」としてのコメントの使用。これが、バージョン管理システムのログの目的です。コードには次のようなものが散らかっています:
// 05-24-2011 (John Doe): Changed this method to use Foo class instead of Bar
通常、コメントアウトされている古いコードが含まれています(これもVCSシステムのポイントなので、新しいコードが記述された後にコードに含める必要はありません)。また、「なぜこれが必要なのか?」またはさらに悪いことに、「これはおそらく名前を変更する必要があります」(名前を変更するための高度なツールがあるため、そのコメントを書くのに時間がかかったため、名前を変更できた可能性があります)。繰り返しますが、私はこれらのコメントの両方を定期的に扱います。
// (John Doe) 05-24-2011 not sure why we are using this object?
FooBar oFooBar = Quux.GetFooBar(iFooBarID, bSomeBool);
oFooBar.DiscombobulateBaz();
// (John Doe). This method is poorly named, it's used for more
// than just frazzling arvadents
public int FrazzleArvadent(int iArvadentID)
少し変わった答えですが、コメントの種類は*コメントなし*です。
コードが明確でクリーンで、正直:
コメントは必要です[〜#〜] [〜#〜]コメントは必要ありません。
コメントは嘘をつく で、維持するのが難しい。 (それについて話しているグーグルの多くのリンクの1つ)
意図を示すためにメソッドに名前を付けて、可能な限り 単一責任の原則 に準拠するようにしてください。そうすれば、コードは厄介なコメントを必要とせずに簡単に読み進めることができます。
(いくつかのコード例については bronumskiの回答 を参照してください)
コードリーダーは通常、次の3つの質問に答えようとします。
それ以外はすべてコードで表現する必要があります。散文を書くように、これは芸術であり、多くの練習が必要です。コードが理解できるかどうかを知る唯一の方法は、他の誰かにコードを読んでもらうことです。理解できないときは口頭で説明しないでください。コードを改善します。最後の手段としてコメントを追加します。
「ダブルレングス」と表示されたら、「測定単位は?」と尋ねます。コメントを追加しないでください。変数名を変更します。コードのブロックが表示され、「これは何をするのですか?」と言う場合は、コメントを追加しないでください。意味のある名前で関数を抽出します。 17個の引数が必要になるため関数を抽出できない場合は、コードをリファクタリングしてください。