カテゴリー
エンジニアリング

プログラミングの命名規則

プログラミングで使用する命名規則のまとめ

キャメルケース(ローワーキャメルケース)

1番先頭の単語の先頭文字は小文字、それ以外の単語の先頭文字は大文字にする。

ラクダのこぶのイメージからつけられた名前です。

例)sendEmailNotification

パスカルケース(アッパーキャメルケース)

単語の先頭文字を大文字にする。

例)SendEmailNotification

スネークケース

単語と単語を 「 _ 」(アンダーバー)でつなぐ。

地面を這うヘビをイメージしてつけられた名前です。

例)send_email_notification

ケバブケース(チェインケース)

単語と単語を 「 - 」(ハイフン)でつなぐ。

串刺しのケバブをイメージしてつけられた名前です。

例)send-email-notification

コンスタントケース

全文字を大文字にする。単語と単語は「 _ 」(アンダーバー)でつなぐ。

例)SEND_EMAIL_NOTIFICATION

カテゴリー
読みやすいコード

あいまいな代名詞を避ける/Avoid Ambiguous Pronouns

代名詞は非常に混乱させることがあります。
読者が代名詞を「解決する」ために余分な作業が必要です。 場合によっては、「それ」または「これ」が何を指しているのかは不明です。

ここに例があります:

// Insert the data into the cache, but check if it's too big first.


このコメントでは、「それ」はデータまたはキャッシュを参照する可能性があります。 おそらく、残りのコードを読むことでそれを理解できるでしょう。

しかし、そうする必要がある場合、コメントのポイントは何ですか?

最も安全なことは、混乱の可能性がある場合に代名詞を "記入する"ことです。 前の例では、「それ」が「データ」だったとしましょう。

// Insert the data into the cache, but check if the data is too big first.

これが最も簡単な変更です。 また、文を再構成して「それ」を完全に明確にすることもできます。

// If the data is small enough, insert it into the cache.

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

コメントをコンパクトに保つ/Keep Comments Compact

C ++型定義のコメントの例を示します。

// The int is the CategoryType.
// The first float in the inner pair is the 'score',
// the second is the 'weight'.
typedef hash_map > ScoreMap;

しかし、なぜそれを説明するのに3行を使用するのですか?1行で説明できますか?

// CategoryType -> (score, weight)
typedef hash_map > ScoreMap;

コメントに3行のスペースが必要なものもありますがが、これはそうではありません。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

悪名高いGoto/The Infamous goto

C以外の言語では、gotoよりよい方法がための非常に多くあるため、gotoを使用する必要はほとんどありません。 gotoはまた、手に負えなくなってコードを追跡しにくくすることでも有名です。

しかし、さまざまなCプロジェクト(とりわけLinuxカーネル)で使用されているgotoを見ることができます。 gotoのすべての使い方を冒涜として却下する前に、なぜgotoの使い方が他のものより優れているのかを解明することは有用です。

gotoの最も単純で無邪気な使い方は、関数の一番下に1つの出口を置いたものです:

if (p == NULL) goto exit;
…
exit: 
    fclose(file1);
    fclose(file2);
    …
    return;

これがgotoの唯一の形式であれば、gotoはあまり問題にならないでしょう。

問題は複数のgotoターゲットがある場合、特にそのパスが交差する場合に発生します。

特に、上向きに動いているgotosは本当のスパゲッティコードを作ることができ、確かに構造化ループに置き換えることができます。 ほとんどの場合、gotoは避けるべきです。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

ファンクションからの早期リターン/Returning Early from a Function


いくつかのコーダーは、関数が複数のreturn文を持つべきではないと信じています。 これはナンセンスです。 関数から早期に返すことは、まったく問題ありません。しばしば望ましいことです。 例えば:

public boolean Contains(String str, String substr) { 
    if (str == null || substr == null) return false; 
    if (substr.equals("")) return true;
    …
}


これらの "ガード句"なしでこの機能を実装することは、非常に不自然なことになります。
単一の出口点を求める動機の1つは、関数の最後にあるすべてのクリーンアップ・コードが確実に呼び出されるようにすることです。 しかし、現代の言語は、この保証を達成するためのより洗練された方法を提供します。

Language / Structured idiom for cleanup code
C++ / destructors
Java, Python / try finally
Python / with
C# / using

純粋なCでは、関数が終了したときに特定のコードをトリガーするメカニズムはありません。 だから、多くのクリーンアップコードを持つ大きな関数がある場合、早期返却は正しく行うのが難しいかもしれません。

この場合、他のオプションには、関数のリファクタリング、またはgotoクリーンアップの賢明な使用さえ含まれます。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

?:条件式(a.k.a. “三項演算子”)/ ?: Conditional Expression (a.k.a. “Ternary Operator”)

Cのような言語では、条件式をcond ? a:bとして書くことができますか?

これは本質的に

if(cond){a} else {b}

を書くためのコンパクトな方法です。

その可読性への影響は議論の余地があります。 提案者は、そうしなければ複数の行を必要とする何かを1行に書くのは良い方法だと思っています。反対派は、読んだり混乱したり、デバッガでステップするのが難しいと主張している。

ここでは、三項演算子が読みやすく、コンパクトであるケースを示します。

time_str += (hour >= 12) ? "pm" : "am";

三項演算子を避けて、次のように書くことができます。

if (hour >= 12) {
    time_str += "pm";
} else {
    time_str += "am";
}

それは引き出されて冗長なビットです。 この場合、条件式は妥当と思われます。 しかし、これらの表現はすぐに読みにくくなる可能性があります。

return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent);

ここで、三項演算子は2つの単純な値の間で選択するだけではなくなりました。 このようなコードを書く動機は、通常「すべてを1行に詰め込む」ことです。

キー・アイデア
行数を最小限にする代わりに、誰かがそれを理解するのに必要な時間を最小限に抑えることがより良い指標となります。

if / elseステートメントでロジックをスペルアウトすると、コードがより自然になります。

if (exponent >= 0) {
    return mantissa * (1 << exponent);
} else {
    return mantissa / (1 << -exponent);
}

助言

デフォルトでは、if / elseを使用します。 三項演算子?:は、最も簡単な場合にのみ使用する必要があります。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

ifーelseブロックの順序/The Order of if-else Blocks

if / elseステートメントを書くときは、通常、ブロックの順序を入れ替える自由があります。 たとえば、次のように書くことができます。

if (a == b) {
  // Case One … 
} else {
  // Case Two …
}

or as:

if (a != b) {
  // Case Two …
} else {
  // Case One …
}

あなたはこれについてこれまであまり考えていなかったかもしれませんが、いくつかのケースでは、他よりも一方の順序を好む正当な理由があります:

•負ではなく正のケースを最初に扱うことをお勧めします。たとえば、if(!debug)ではなくif(debug)です。

•最初に単純なケースを扱うことをお勧めします。 この方法では、ifとelseの両方を画面上に同時に表示することもできます。

•より興味深い、またははっきりしたケースを優先して処理することを優先します。

時々これらの好みは衝突し、あなたは判断を下さなければなりません。 しかし、多くの場合、勝者は明らかです。

たとえば、Webサーバーがあるかどうかに基づいて応答を構築しているとします。
URLにはクエリパラメータexpand_allが含まれています:

if (!url.HasQueryParameter("expand_all")) {
    response.Render(items);
    …
} else {
    for (int i = 0; i < items.size(); i++) {
        items[i].Expand();
    }
    …
}


読者が最初の行を見ると、すぐにexpand_allのケースについて考えます。

「ピンクの象は考えないで」と誰かが言うようなものです。 あなたはそれを考えずにはいられません。「しないでください」は、より珍しい「ピンクの象」に溺れてしまいます。

ここで、expand_allはピンクの象です。 これはより興味深いケースであるため(そしてポジティブなケースでもあります)、最初に対処しましょう。

     if (url.HasQueryParameter("expand_all")) {
         for (int i = 0; i < items.size(); i++) {
             items[i].Expand();
         }
         …
         } else {
             response.Render(items);
             … 
    }


一方、ここでは、ネガティブケースがよりシンプルで興味深い/危険なケースであるため、最初に対処します。

if not file:
    # Log the error …
else:
    # …


繰り返しになりますが、詳細によっては、これは判断の呼び名になる場合があります。

要約すると、私たちのアドバイスは、これらの要因に注意を払い、if / elseが厄介な順序にある場合に注意することです。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

条件文中の引数の順序/The Order of Arguments in Conditionals

どちらのコードを読みやすいでしょうか

if (length >= 10)

or

if (10 <= length)

ほとんどのプログラマーにとって、最初のものははるかに読みやすくなっています。 しかし、次の2つはどうでしょうか?

while (bytes_received < bytes_expected) 

or

while (bytes_expected > bytes_received)

ここでも、最初のバージョンは読みやすくなっています。 しかし、なぜ? 一般的なルールは何ですか?

a < bまたは b > aを書く方が良いかどうかをどのように判断しますか?

私たちが役に立つと思っているガイドラインは次のとおりです。

左側 / 右側

表現が「調査されている」という表現は、その価値がより流動的である。 / 比較される式。その値はより一定です。

このガイドラインは英語の使用法に一致します。「年間10万ドル以上稼いだ場合」または「18歳以上の場合」と言うのはかなり自然なことです。

「18歳があなたの年齢以下の場合」と言うのは不自然です。

これは、(bytes_received < bytes_expected)がより読みやすい理由を説明しています。

bytes_receivedは、確認している値であり、ループが実行されるにつれて増加します。

bytes_expectedは、比較される値より「安定した」値です。

ヨーダ記法:今でも使えますか?

いくつかの言語(CおよびC ++を含むがJavaは含まない)では、if条件の中に代入を入れることは正当です:

if(obj = NULL)…

おそらくこれはバグであり、プログラマーは実際には次のことを意味します。

if(obj == NULL)…

このようなバグを防ぐために、多くのプログラマは引数の順序を切り替えます。

if(NULL == obj)…

これは、==が誤って=と書かれた場合、if(NULL = obj)という式もコンパイルされません。(ヨーダが言うように、「私が持っていることについて言うことは何もない。」)

残念ながら、順序を切り替えるとコードが読みにくくなります。

ありがたいことに、最新のコンパイラはif(obj = NULL)のようにコードを警告するため、「ヨーダ記法」は過去のものになりつつあります。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

do-whileループを避ける/Avoid do-while Loops

Perlだけでなく、多くの尊敬されるプログラミング言語にdo {式} while(条件)ループがあります。 表現は少なくとも1回実行されます。 ここに例があります:

// Search through the list, starting at 'node', for the given 'name'.
// Don't consider more than 'max_length' nodes.
public boolean ListHasNode(Node node, String name, int max_length) {
    do {
        if (node.name().equals(name))
            return true;
        node = node.next();
    } while (node != null && --max_length > 0);
    return false;
}

do / whileループに関して奇妙なことは、コードブロックがその下の条件に基づいて再実行されるかどうかということです。 通常、論理条件は、それらが保護するコードの上にあります。

これは、if、while、およびforステートメントで動作する方法です。 通常、上から下にコードを読み込むので、これはdo / whileを少し不自然にします。 多くの読者がコードを2度読んでしまいます。

whileループは、内部のコードブロックを読み取る前にすべての反復の条件を知っているため、読みやすくなっています。 しかしdo / whileを削除するだけでコードを複製するのはばかげているでしょう:

// Imitating a do/while — DON'T DO THIS!
     body
while (condition) { 
    body (again)
}


幸いなことに、実際にはほとんどのdo / whileループは次のように書かれている可能性があります。
whileループは始まります:

public boolean ListHasNode(Node node, String name, int max_length) {
    while (node != null && max_length-- > 0) {
        if (node.name().equals(name)) return true;
        node = node.next();
    }
    return false;
}


このバージョンには、max_lengthが0の場合やnodeがnullの場合でも動作するという利点があります。

do / whileを避けるもう一つの理由は、continue文がその内部で混乱する可能性があるということです。 たとえば、このコードは何をしますか?

do {
    continue;
} while (false);

永久にループするのか、それとも1回だけループするのか? ほとんどのプログラマーはそれについて立ち止まって考える必要があります。 (ループは1回だけです。)

全体として、C ++の作成者であるBjarne Stroustrupはそれを最もよく述べています(C ++プログラミング言語で):私の経験では、doステートメントはエラーと混乱の源です。

…「私がそれを見ることができる前に」という条件を好む。 したがって、私はdo文を避けがちです。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

情報密な言葉を使う/Use Information-Dense Words

何年もプログラミングをしていると、同じ一般的な問題と解決策が繰り返し出てきます。

しばしば、これらのパターン/イディオムを記述するために開発された特定の単語やフレーズがあります。 これらの言葉を使用すると、コメントをもっとコンパクトにすることができます。

たとえば、あなたのコメントが次のようになったとします。

//このクラスには、データベースと同じ情報を格納する多数のメンバーが含まれていますが、速度を上げるためにここに格納されています。 このクラスが後で読み取られるとき、それらのメンバーが最初にチェックされ、それらが存在するかどうかが確認され、存在する場合は返されます。 それ以外の場合は、データベースが読み取られ、そのデータは次回のためにこれらのフィールドに格納されます。

代わりに、次のように言うことができます。

//このクラスは、データベースへのキャッシングレイヤとして機能します。

別の例として、次のようなコメントの場合:

//通りの住所から余分な空白を削除し、「Avenue」を「Ave」に変えるなど、他の多くのクリーンアップを実行します このように、2つの異なる住所が入力されている場合(少し異なる方法で入力された場合)、それらは同じクリーンアップバージョンを持ち、これらが等しいことを検出できます。

次のようにすることができます:

//住所を正規化する(余分なスペースを削除する、 "Avenue" - > "Ave."など)

“heuristic,”「ヒューリスティック」、“brute- force,”「ブルートフォース」、“naive solution,”「ナイーブな解決策」など、多くの意味を詰め込む言葉やフレーズがたくさんあります。

少し長めになっていると思われるコメントがある場合は、それが典型的なプログラミング状況として記述できるかどうかを確認してください。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)