プログラムのソースコードを他人に見せるためにはきれいに整理して書くことが大事になってきます。
プログラミング言語によって書き方は異なるので一概には言えないので、その言語にあった書き方に置き換えてください。
用語について
この記事には一部専門用語が出てきます。
名称 | 表記例 | 備考 |
---|---|---|
アッパーキャメルケース(UCC[4])、またはパスカルケース[5] | GetInputReader |
複合語の先頭を、大文字で書き始める。 |
ローワーキャメルケース(LCC[6])、または単にキャメルケース | getInputReader |
複合語の先頭を、小文字で書き始める。 |
引用: https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9
この記事では、先頭を大文字にすることをパスカルケース、先頭を小文字にするのをキャメルケースと書きます。
命名規則
メソッドや変数の名前の書き方に規則を持たせることで、それがどこに宣言されているのかわかるようになります。
これは必ず守るようにしましょう。そうすることでバグの発生を抑えることができます。
メソッド名の先頭はパスカルケース、関数名はキャメルケース
言語によってメソッド/関数と分かれます。基本的にオブジェクト指向の言語はメソッドでそうでない場合は関数と言われます。
例えばJavaやC#ではメソッド、Javascript等の言語は関数となりますね。
グローバル変数はパスカルケース、ローカル変数はキャメルケース
かなり大事になってくるポイントです。グローバル変数は必ずパスカルケースで命名するようにしましょう。そうすることで他のメソッドから値を変更される可能性があるとひと目でわかります。
また、関数ポインターをローカル変数に入れる場合、それは変数なのでキャメルケースで記述すべきです。
プロパティはパスカルケース
プロパティの場合はパスカルケースで記述するようにします。あくまで他から値を変更される可能性のあるものはすべてパスカルケースです。
名前空間/クラス名はパスカルケース
クラス名の場合はパスカルケースを利用します。
これは人によって変わりますが、privateクラスなどの外部ライブラリから変更されることがないクラス等はキャメルケースにする場合もあります。
クラス内のクラスの場合はこれでもいいと思いますが、そうではない場合、少し賛否両論な気がします。
パラメータはキャメルケース
パラメータは実はパラメータ変数といい、ローカル変数の一種です。
言語次第ではパラメータ変数の値を変更することもできるため、実質普通の変数として利用することもできるでしょう。
補足: リスクによってキャメルとパスカルを使い分ける
この場合のリスクとは、他から値を変更される可能性があるか、利用頻度が高いかなどです。
先ほどの命名規則とは、グローバルにあるメンバーならパスカルケース、そうでないローカルはキャメルケースでしたね。
更にオブジェクト指向がない言語の場合はクラスというものを持たないため、どうしても関数はグローバル空間に存在することになります。
実質、クラスのようなものを定義することができる言語の場合なんとも言えない部分が出てくると思います。
クラスだとわかるようにするためにパスカルケースにするという考えはありだと思います。
バージョン管理
共同開発の場合、そのメンバーの意味、パラメーターの意味、誰が作ったか、どのバージョンからあるメンバーかなど、様々な情報を記す必要があります。
言語によって差はありますが、私の方法を書きます。
説明は必要最低限に、でも伝わるように
コード: void Create(string name) { … }
Java: /* Create a file. */
C#: <summary>Create a file.</summary>
説明が長いと読み手にとって非常に面倒です。長い補足が必要になるようなメソッド/関数はそもそも作るべきではありません。
できるだけ短く収めて、おかしなパラメータを指定した場合はすぐに例外を投げるようにするのがベストと言えます。
パラメーターにも必ず説明を付ける
コード: void Create(string name) { … }
Java: /* @param name name of the file. */
C#: <param name=”name”>Name of the file.</param>
個人開発でもそうですが、長期に渡って開発するものならばパラメータにも説明はつけるべきです。
たまに1単語で様々な意味に受け取れるものも存在します。簡単にでも説明しましょう。
私が過去にみた例ですが、ファイルの詳細情報を受け取るクラスがありました。
そのクラスは個人作ので、その言語には既に全く同じことができるクラスがあったのですが…機能がかなり食い違っていました。
用意されていたクラス | 個人作のクラス | |
Name | ファイルの名前(拡張子を含む) | ファイル名(拡張子を含まない) |
FullName | ファイルのフルパス | ファイル名(拡張子を含む) |
Extension | 拡張子(最初の.を含む) | 拡張子(最初の.を含まない) |
説明があれば混乱せずに済んだかもしれません。細かいことでも説明は必要です。
戻り値の情報も書いておく
コード: int GetHandle();
C#: <returns>Handle of the window. If throw a error, return 0.</returns>
Java: /* @return Handle of the window. If throw a error, return 0. */
戻り値で何が返されるのかを返します。WinAPIとかでよく見かけるのが「成功時には0以外、失敗すると0が返される」というのをよく見かけます。
最近の言語では失敗すれば例外を投げたり、戻り値にnullを返すというものもあります。
その辺りが食い違うと例外処理してたのに先に進んでしまったっていうのが起きてしまうので書いておきましょう。
誰が作ったかを残しておく
C#: /// Created by Sharoron.
Java: /* @created by Sharoron */
別にあとから責任追及をするわけではありませんが、誰が作っらメンバーなのかを書いておきましょう。
そのメンバーが追加されたバージョンを記す
C#: <summary>Create a file. Since:2.1</summary>
Java: /* @since 2.1 */
C#の場合、summaryに書くのが無難な気がします。
大事なのはソースコードを書いた時間や日じゃなくてバージョンだと思います。もちろん情報が多いほうがいいですがごちゃごちゃするのも面倒ですよね
どのバージョンから追加された機能なのかあるとバージョン管理や機能の競合を防ぐことができます。
その他の大事な書き方
1つに詰め込み過ぎない
よく、1つのメソッド/関数の中が数百行もあるようなものを見かけます。俗にいうウンコードというものです。
必要なのは、1つのメソッド/関数でたくさんのことができるのではなく、機能を部分部分にわけて、それを他に流用できるようにすることです。
1つにたくさんのことができるものを作りたいならば、作ったメソッド/関数を組み合わせるだけのを作ればいいのです。
これは機能強度と結合性というもので、できるだけバグを作らないための方法となります。
参考になるサイト: モジュールの強度と結合度
大雑把な機能によってファイルを分ける
Javascriptのようなファイルを分けると読み込みが遅くなる場合を除いて、ファイルは機能によって分けるべきです。但しその場合、分け方は統一しましょう。
例えば、C#やJavaの場合はクラスによって分けられていることが多いです。ですがたまに似た機能を集めてファイルを分けている人もいます。
大事なのはそのクラスがどこにあるのか、探して時間がかかるような状況を作らないということ。
寄せ集めてどこにあるのかわからなくなるぐらいなら分けまくってファイル数が多くなる方がましでしょう。
なお、C#/Java/C++などのコンパイルされる言語は、最終的には1ファイルになるので分けたからといって速度が遅くなることはありません。