web-dev-qa-db-ja.com

最短時間でレビューできるようにコードを文書化するにはどうすればよいですか?

コードを文書化して、数か月後にもう一度コードを読んだり閲覧したりする必要が最小限になるようにしたいと考えています。

さまざまな種類のドキュメント(ソースコード内と外部、シーケンス図など)があることを知っています。

コードを文書化するための効率的な方法を知りたいので、数か月後にコードを確認したいときに、コードの読み取りとコードフローの理解に費やす時間を減らします。

21
Hamed_gibago

他の回答が推奨するいくつかのことに同意しないことを認めなければならないので、2セントを投げます。

コメント

ドキュメントは非常に見知らぬ人がコードを読むのに役立ちます。通常、多くのことは、すぐに読んで理解するのに十分なほど冗長ではないので、自分が何をしているかを説明する必要があります。

編集:コメントセクションのディスカッションで問題が指摘されています。通常、badコードを記述するときにオーバーコメントが行われます。

あなたの作品へのコメントは正確かつ最小限であるべきですが、私の意見では、間違いなく存在すべきです。コードの15行ごとに少なくともコメント。たとえば、コードのブロックの上に、実行していることに関する行を追加します。

_def login(username: str, password: str, create_session: bool = True):

    # Filter the user we need from the database
    hash = md5(password)
    users = db.table("users", db_entities.USER)
    results = [x for x in users.query(lambda c: c.get("username") == username and c.get("password_hash") == hash)]


    if len(results) == 0:
        return None, None
    else:
        # Create a login session record in the database.
        if create_session:
            sessions = db.table("sessions", db_entities.SESSION)
            ses = sessions.new()
            ses.set("username", username) \
                .set("expiery", 31536000 + time.time())
            sessions.update(ses)
            return results[0], ses
        else:
            return results[0], None
_

whyおよびwhatを説明する最小限のコメントは、コード全体で非常に役立ちます。私は述べている答えに同意しません

コメントを含むコードに遭遇した場合、私は最悪の事態に備えます。コードは悪い可能性が高く、正直に言うとコメントも悪い可能性が高いです。

多くの場合、適切なコードが文書化されています。悪いプログラマーが「わかりました、私のコードは悪いです。わかりやすくするためにいくつかの文を追加しましょう」のようなドキュメントを見るのは事実です。

はい、これはかなり頻繁に発生しますが、クリーンなコードを書く優れたプログラマーは、コードに戻って、関数をそのように動作させたい理由、またはなぜそれが必要なのかを理解したいと思うことも事実です。少し冗長に見える線など.

はい、明らかなことを説明するコメント、不明確なコメント、「このコードが文書化されている、そう、なんでも」を確認するためにまとめられたコメントは、コードの匂いです。彼らはコードを読みにくくし、イライラさせます。 (以下の例を追加)

_# Logging into Gmail when the module is imported
_client = login()
def get_client():
    global _client
    return _client
_

明確化の例:「たわごとはありません。シャーロック。_client = login()はメールサービスにログインしますか?OMG!」

明確化:login()メソッドは、上記の例のlogin()メソッドとは関係ありません。

しかし、標準に一致するコメント、理由を説明し、方法は説明しない正しい質問に答えるは、非常に役立ちます(very)。

インラインコメント

[〜#〜]ない[〜#〜](そして、もっと大きく書けるとしたら、そうします)すべきことの1つは、コードの同じ行にコメントを書くことです。これはコメントを非常に行固有にするため、コードにコメントする目的が完全に失われます。

たとえば、不適切なインラインコメント:

_outer = MIMEText(details["message"]) # Constructing a new MIMEText object
outer["To"] = details["to"] # Setting message recipient
outer["From"] = "xAI No-Reply" # Setting message sender
outer["Subject"] = details["subject"] # Setting message subject
outer.preamble = "You will not see this in a MIME-aware mail reader.\n" # I don't know what I'm doing here, I copied this from SO.
msg = outer.as_string() # Getting the string of the message
_client = details["client"] # Assigning the client
_client.sendmail(SENDER, details["to"], msg) # Sending the mail
_

コメントなしでこのコードを読んで理解する方がはるかに簡単で、乱雑で読みにくくなります。

代わりに、コード内のコメントはコードのブロックの上に配置し、コードブロックの読み取り中に発生する可能性がある重要な質問に回答する必要があります。

_# Constructing the email object with the values 
# we received from the parameter of send_mail(details)
outer = MIMEText(details["message"])
outer["To"] = details["to"]
outer["From"] = "xAI No-Reply"
outer["Subject"] = details["subject"]
outer.preamble = "You will not see this in a MIME-aware mail reader.\n"
msg = outer.as_string()

# Sending the mail using the global client (obtained using login())
_client = details["client"]
_client.sendmail(SENDER, details["to"], msg)
_

はるかに明確ですよね?これで、login()関数を使用し、使用したすべてのパラメータをsend_mail()に提供する必要があることもわかりました。少しは役立ちますが、まだ1つ欠けています。

機能ドキュメント

広く議論されてきました。あなたは常にあなたの読者にあなたの機能が何であるか、なぜ、そしてそれが何をするかを知らせるべきです。それがどのように行われるか、これはドキュメンテーションには属していませんが、おそらく関数の脚注に属しています。

パラメータが何であるかを期待し、特定の方法で取得または作成する場合は、それらを明確に説明する必要があります。関数が返すもの、その使用法などを宣言する必要があります。

繰り返しますが、これは私のコードを書くときの私の意見と方法論です。それらだけでなく、それらは私が他の答えに同意できなかったもののほんの一部です。ああ、もちろん、コメントだけでコードが読み取られるのではなく、コード自体も読み取られます。 クリーンなコードを記述し、理解可能で保守可能。コーディングしながら、自分の将来について考えてください;-)

16
Yotam Salmon

IMOに最適なドキュメントは、実際には必要ないドキュメントです。ドキュメントやコメントを書くのも嫌いです。

それが言われていると:

  • 読みやすく話しやすい名前を選びます。 nを使用せず、代わりにnumberOfItemsFoundを使用してください。
  • すべてを1行にプッシュするのではなく、定数変数に計算の一部を格納するのをためらわないでください。
  • 部分的なタスクをブランチから独自の(インライン)関数に移動します(それらを再利用している場合、または親関数が長くて面倒になる場合)。
  • より精巧にし、コードが本当に必要な場合にのみ可読性よりもコードを最適化します。
55
Mario

コードをドキュメントとして扱う

あなたのコードはあなたの主要なドキュメントです。結果のアプリやライブラリなどが実際に何をするかを正確に説明します。そのため、そのコードの理解をスピードアップしようとする試みは、コード自体から始める必要があります。

読みやすいコードを書く方法についてはたくさん書かれていますが、重要なポイントのいくつかは次のとおりです。

  • 悪いコードを説明するのにコメントに頼らないでください、コードをより良くしてコメントを取り除いてください、
  • 短いフォーカス関数、メソッド、クラスなどを書く
  • コンテキストに適した名前を使用します(たとえば、nはループに適しています。より大きなスコープのアイテムには、より長い説明的な名前が必要です)。
  • 関数名をコメントのように扱います。たとえば、UpdtTblを名前として使用できる場合は、指定されたルールでテーブルを更新することを説明するコメントでUpdateTableContentsWithSuppliedRulesを使用しないでください。
  • 可変性を避けます。変数の内容を変更するたびに、コードが複雑になります。可能な場合は、その新しい値を新しい変数(適切な名前)に割り当てます。
  • 最後に、そして最も重要なこととして、「賢い」コードを避けます。唯一の本当の賢いコードは、読みやすいコードです。複雑なコードを書いて、「すごい、ここでは賢くないですか?」と思う場合、答えはほぼ間違いなく「いいえ、あなたはそうではありません」です。

コードを読むのが上手になる

コードを読むことは、それがどれほど単純であるかに関係なく、習得されたスキルです。当然、コードを読むのは得意ではありません。練習が必要です。たくさんの練習。したがって、たとえば、Githubなどにアクセスして、ライブラリを使用するだけでなく、使用するライブラリのコードを読んでください。それを読んで読むコードを見つけてください。

コメントはコードのにおいです

そうして初めて、他のタイプのドキュメントにたどり着きます。まず、前述のように、コメントを避けます。コメントを含むコードに遭遇した場合、私は最悪の事態に備えます。コードが悪い可能性が高く、正直なところ、コメントも悪い可能性があります。コードを介してうまく通信できない人は、自然言語を介してよりよく通信することができる可能性は低いです。

自動生成されたAPIドキュメントに注意してください

また、自動生成されたAPIドキュメントにも注意してください。私がそのようなドキュメントを読むことに頼らなければならないなら、それはあなたのコードがとても読みにくいからです。繰り返しますが、コードを単純にすれば、直接読み取ることができます。

テストもドキュメントです

テストもドキュメントです。したがって、ユニットテストを雑用として扱わないでください。コードがどのように機能し、使用されることが意図されているかについて、他のユーザー(6か月後の自分がここに含まれる)と通信する方法としてそれらを扱います。

役に立ったら絵を描く

UMLが好きなら、ぜひ自分にぴったりのツールを見つけて、コードからUML図を生成してください。これを使用してコードを生成しようとすることは決してありません。それは設計ツールとしては良くなく、結果として恐ろしいコードになってしまいます。

「1000フィート」のビュードキュメントがあります

最後に、概要ドキュメントを自分で作成します。アプリは何をしますか?どうやってやるの?他のどのシステムに接続しますか?そういうもの。ただし、ここではコード構造を記述しないでください。コードにそれをさせてください。このドキュメントで、そもそもなぜコードを書いたのかを思い出させてください。

25
David Arno

カバーレターを提供する

あなたが非常に技術的な領域にいない限り、コードに関するほとんどの質問は「方法」ではなく、「なぜ」または「何」に関するものです。

このように、人々があなたのコードを見る必要がないようにする方法は、それについて短い説明を書くことです。これの利点は、説明の概要を非常に簡単に編集できることと、これがはるかにアクセスしやすいことです。 (コードを見ることができない/許可されていない人にも)。

技術的な人でも、カバーレターは、どこで何かを探すべきかについてのガイダンスを提供する必要があります。

シンプル非常に最小限のポイント:

  1. はじめに、このコード(ベース)が存在する理由
  2. コードのサブセットが果たす機能
  3. コードはどこですか(たとえば、スクリプト名)

  1. このスクリプトセットはStackOverflowをスクレイピングし、Dennis Jaheruddinによる回答に賛成票を投じます
  2. a。このスクリプトは、htmlの解析を担当し、適切なユーザーかどうかを分析します
  3. a。スクリプトはScrapeAndVote/RecognizeDennis.scrにあります。
5

通常、それぞれがコンパイルおよび動作する中間ステップを表す個別のコミットを作成することで得られる最大の速度向上。

したがって、特定の機能を実装するために関数に新しいパラメーターを導入する必要がある場合、宣言、定義、およびすべての呼び出しサイトでパラメーターを追加する以外に何もしない1つのコミットがあります。次に、次のコミットで機能が導入され、3番目のコミットでは、新しい機能を利用する呼び出しサイトが更新されます。

純粋に機械的な変更がすぐに一目でわかり、邪魔にならないため、これは簡単に確認できます。

同様に、コードを再フォーマットする場合、それは常に個別のコミットである必要があります。

1
Simon Richter

既存の回答の間には明らかな意見の相違点が1つまたは2つありますが、強調する場合は、通常のアドバイスを要約して、誰がどこから来たのかを明確にするようにします。

  1. まず、クリーンなコードを記述します。その他の「ドキュメント」は、その後自動的に処理されます。クリーンなコードは、そもそも学ぶべき一連の原則です。単一責任クラス、1つのことを行う短いメソッド、適切な変数とメソッド名 これらよりも優れたクラス/型名 メタファー(MultiButtSupporterをソーダと呼ぶなど)、要件を示す単体テスト、DRY、SOLID、一貫したパラダイムなど。
  2. コードは、コードがどのように機能するかを明らかにします。コメントは、コードが機能する理由を明らかにします。たとえば、+ 1で「1つのオフによるエラーを防止する」、または「この教科書またはWebページから派生した」という複雑な式を説明します。
  3. コメントで何をしていても、上記のポイント1は、クリーンなコードでそれを十分に達成する可能性があります。コメントを失敗/必要な悪として見るか、どちらかが編集されたときにコードと同期が取れなくなった場合に嘘をつけます。コメントは、不適切に記述されたコードを補うものであってはなりません。なぜ、コメントは、コードよりも才能や注意をもって書かれるのでしょうか。

一方、私が何か間違っているとすれば、おそらく反対の方向に進みすぎて、コメントはほとんど使用しません。コードレビュー担当者は、バランスが間違っているかどうかを通知しますが、上記の3点計画に従うように意識的に努力すれば、とにかく最適に近づくでしょう。

1
J.G.