はじめに
こんにちは。プログラマーのTです。
株式会社ジーンでは、社内でいろいろな勉強会が行われています。前回は、コーディング・テスト勉強会のうち、コードの見やすさについてお伝えしました。
今回は、前回紹介した見やすさに影響する要素のうち、説明していなかった命名とコメントについて解説してみようと思います。
命名について
一般的なプログラムでは、制御文などの予約語以外のものは、任意の名前を付けることができます。多くのプログラミング言語に共通するのは次のようなものでしょう。
• クラス
• 関数
• 変数、定数、列挙型
命名はプログラミング言語の重要な機能です。ここからは命名がどのように機能するか見ていきましょう。
命名が機能していない例
以下の例(1)のコードを見てください。
何も手掛かりがないので、行われている処理を読んで理解するか、デバッガーで追うことになるでしょう。変数に格納されている値から、変数が何の役割なのか推測します。その役割と無意味な変数名との結びつきを覚えます。そのようにプログラムを読んでいくことになると思います。
そして結果的にプログラムを読んだとしても、何をするものなのかはわからないのではないでしょうか。
続いて、以下の例(2)のプログラムを見てください。
これは例(1)と命名以外は同じプログラムです。何をするプログラムか名前から推測できます。それぞれの変数が何を意味するのかもわかります。命名の意味をなしていない例(1)と比較すると、次のような点が異なります。
• コードを読む・実行する必要がない
• 無意味な変数名とその内容を結び付けて覚える必要がない
人間が一時的に覚えておけることの数は、7±2個程度といわれています。
ですので、上記の例(1)のプログラムのように、読む必要・覚える必要があるプログラムは、人間にとってはあまりいいプログラムとは言えません。
マジックナンバーについて
マジックナンバーも、無意味な命名とほぼ同じ問題を持ちます。次の例を見てみましょう。
この0,1,2が何の意味になるのかを推察するのはかなり大変です。この例では、マジックナンバーが処理のブロックに関係するものとなっているため、ブロック内で行われていることを読むか実行して理解する必要があります。
この場合、0...立ち状態, 1...歩き状態, 2...ジャンプ中 のような対応を、プログラマーが勝手に割り当てています。これは隠された情報で、数字だけでは推測することができません。
これらの数字に意味を付け、読めるようにするのが定数や列挙型です。
これで、コンピュータが実際に処理する0,1,2といった数字に、具体的な意味を付与することができました。
命名方法について
ここからは、先ほど挙げた3つの項目(クラス、関数、変数)について、具体的にどのような命名を行うか説明します。英語でつけることになるので、ある程度英語のことも理解しておくとよりよい命名ができるでしょう。
クラス
クラス型は、名詞でつけます。名詞のほかに、動作主名詞もよくつかわれます。動作主名詞とは~~する人、~~するものといった意味で、Manager, Controllerなど、動詞に ~er(or) と付くものを指します。
(例)
名詞:Event, Message, Image
動作主名詞: SceneManager, EventController
避けたほうがよい例:ManageScene EventControlなど、語順が逆、動作主ではなく動詞になってしまっているもの。関数名と見分けがつきにくくなるので、避けたほうがよいでしょう。
関数
関数は動詞、または、動詞+目的語の形でつけます。
(例)
動詞: Run, Start, Load, Send
動詞+対象:GetSize, CalcLength, PlayAnimation
避けたほうがよい例:LengthCalc, ItemUse など、動詞が後にきてしまっているもの。クラスや変数といった名詞から始まるものと見分けづらくなります。
変数
変数は名詞でつけます。長くなりすぎない程度に具体的な意味を付与します。
プリミティブ型の変数は、型自体に意味がないので、かならず具体的な意味を付与します。
日付・時間・座標・ベクトル・プリミティブ型のリストなど、比較的小さいクラスや構造体についても、型名だけでなく、具体的な意味を記述します。
クラス型の変数については、型情報だけで十分な場合は型に近い名前を、処理の都合上で型名以外の情報がある場合はそれらを付与します。
迷ったときは
英語の単語や語順に迷ったときは、既存のソースコードを参考にする方法もあります。ゲーム系であれば、Unreal Engine、Unity、DirectX、OpenGLなどの既存のAPIライブラリから似た名前付けを探すことも可能です。
また、最近では、GitHubなどのオープンソース基盤がソースコード検索を提供しています。そちらで、単語や語順に迷ったりした場合に検索してみるのも良いでしょう。
その他、インターネット上にある、和英辞典、類語辞典、例文集、翻訳機能も参考にできますので活用してみてください。
コメント
コメントは、コードの動作には全く影響しませんが、重要な要素です。
コメントについては、コードと重複する説明をするべきではない等、いろいろな議論があります。ここでは、そのあたりは触らず、コメントでしかできないことについて考えてみましょう。
コードの要約
短い関数では、関数名がコードの要約となります。
複数の事柄を行うある程度大きな関数では、数行単位で行われる処理の説明をコードでは記述できません。そういう時にコメントが役立ちます。例えば次のようなものです。
この例では、ストリームについての知識や、std::getline()関数で、改行以外の区切りが使用できるという情報がないとやや読み解きづらいコードです。コメントがあることによって、処理の内容が把握でき、コードの内容が推測しやすくなります。
関数の使いかた
公開するクラスや関数では、それを使う人が迷わないようにコメントを書く必要があります。
特に関数のコメントでは、引数の値の範囲はどこまでOKなのか、nullが許容されるのかなど、宣言だけでは読み取れないものを記述しておくと良いでしょう。通常、このようなコメントは、DoxygenやJavadocなど、特定のコメントスタイルをプロジェクトで定めていることが多いです。
以下はDoxygenスタイルの関数コメントの例です。
なぜそうしているのかわかりづらいコード
例えば、初期化処理において特定の順番で初期化する必要があるといったことや、呼び出し先の関数のバグに対応するために一時的に入れている対応処理など、「なぜそうしているのか」がコードだけでは読み取れないことがあります。そのような処理には、コメントを入れておくと良いでしょう。
コメントについてのまとめ
まず、書いたコードを見て、読み手が理解できるかどうかを考えてみましょう。もちろん、コードを洗練させることも重要です。しかしながら、コードだけでは説明できないこともあることを念頭に入れておき、そういったことはコメントを書いておくと良いでしょう。
おわりに
今回は、命名とコメントについて解説しました。少しでも参考になればと思います。
以上で今回の解説は終わりです。
ありがとうございました。