命名規則 (プログラミング)

命名規則とは、プログラミングを行う際にソースコード上の識別子の名称となる文字列を決定するためのルールを定めたもの。ネーミング規則、ネーミング規約、あるいは命名規約とも呼ぶ。

通常は、ソースコードの可読性や視認性の向上、プログラミング効率およびメンテナンス性の改善などを目的としている。

命名規則は、プログラミング言語の仕様、メモリサイズ等のハードウェア的な制約、エディタや統合開発環境  の機能などに影響を受けていることがある。

1. 命名規則を決めたときの利点
----------------

命名規則を決めた場合の潜在的利点としては、以下のものが挙げられる。

識別子の使用法に関して追加情報を名前に含めることで、ソースコード自体をドキュメント化することができる。
変数の使いまわしによる可読性の低下やバグの発生を防ぐことができる。
プロジェクトおよび開発チーム内で命名について一貫性を持たせることができる。生産性やメンテナンス性の向上につながる。
潜在的な曖昧さを回避し、違いを明確化することができる。
検索置換ツールで間違える可能性を減らすことができる。
ツールによるリファクタリングの自動化が容易になる。
成果物に美しくプロフェッショナルな見た目を与えることができる。
複数のチームが開発したものを統合・再利用するような場合に、名前が衝突することを防ぐことができる。

2. 課題
-----

命名規則の選択とその実施は、論争になりやすく、各人がどんな命名規則が最善かについて意見を持っていることが多い。

さらに、よく知られている命名規則を採用したとしても、全体に実施を徹底させることができなければ、一貫性がなくなり、混乱が生じる。

このような課題は、その命名規則が一貫しておらず、記憶しづらく、利点よりも欠点が多いような場合には、さらに悪化する。

3. ビジネス上の価値
-----------

ソフトウェアシステムやアプリケーションソフトウェアのエンドユーザーが識別子名の良し悪しを意識することはほとんどない。ソースコード上の識別子名は、通常ユーザーインターフェイスに表出することはないからである。しかし、システムを引継いでいく開発者やアナリストにとっては、識別子が適切に選定されていることで、システムが何をしているかを理解したり、さらには新たなビジネス所要に応じてソースコードをどのように修正・拡張すればよいかを判断したりすることが極めて容易となる。

例えばC言語による例として、 double a, b, c; b = 160.0; c = 1500.0; a = b * c; というコードは文法的に間違っているわけではないが、その意図・意味は見当もつかない。どのようにも解釈することができる。少なくともコメントがなければ、各変数が何を意味しているのか、計算式は何を意味しているのかが分からない。

これに対して、 double monthly_pay_jpy, hours_worked, hourly_pay_jpy; hours_worked = 160.0; hourly_pay_jpy = 1500.0; monthly_pay_jpy = hours_worked * hourly_pay_jpy; というコードは、各変数名に意味が込められていることで、たとえコメントがなくとも、少なくともシステムやアプリケーションの基本的な前後関係を理解している人には意味・意図が分かりやすくなる。

また、各種APIや外部で開発されたサードパーティ製のライブラリを利用する場合も、適切な識別子命名規則に基づいて整理されたAPI・ライブラリのほうが、機能を類推しやすくなるため、生産性の向上にもつながる。

ソースファイルや、そのソースファイルを配置するディレクトリの命名規則もまた重要である。適切な命名と分類・階層化をすることで、どのファイルにどのような機能が実装されているのか、ということが分かりやすくなり、メンテナンス性の向上につながる。C++やC#のようなクラスベースのオブジェクト指向プログラミング言語では、一般的にそのソースファイル内で記述される主要なクラスの名前をファイル名にすることが多い。Javaの場合は最上位のpublicクラスを定義するソースファイルの名前は、そのクラスの名前と同じでなければならないという言語仕様上の制約がある。

C/C++のライブラリは、モジュールとともに関数宣言や型定義を含むヘッダーファイルを公開インターフェイスとして提供することが多く、ヘッダーファイルの命名規則も重要となる。

4. 典型的要素
--------

命名規則は実際には、開発する対象や環境に依存する。しかし、多くの命名規則に共通に見られる要素がいくつか存在する。

4.1. 識別子の長さ
-----------

命名規則の最も基本的な規則のうちのひとつは、識別子の長さに関するものである。数値を挙げて上限を設定する場合もあれば、もっと緩やかなガイドラインを設定する場合もある。

識別子長の規則は議論の的になりやすく、学術的な議論にもなっている。適切な長さはケースバイケースであり、一概には決まらない。

考慮すべき点:

タイピングしやすいため、短い識別子が好まれる傾向がある。ただしIDEの入力支援機能が使える場面では、あまり問題とならない。
あまりにも短い識別子は、識別が困難である。
短い識別子では暗号的な名前になるなど意味情報が十分に込められないとして、長い識別子を好む場合もある。
長い識別子はスクリーン上に占める面積が増え、コード全体を素早く読めなくなることから、敬遠される場合がある。
たとえ長い識別子を使っても、そのうち1文字しか差異がない2つの識別子などは一見して区別が困難なこともある。
略語は混乱を招くため控えたほうがよいが、長すぎる正式名称を使うと可読性を損なう。
変数や関数のスコープに応じて長さを変えることもある。 スコープが広い場合は長い名前が好ましいが、スコープが狭い場合は短い名前でもかまわない、など。初期のリンケージエディタには、メモリ使用量を抑えるために変数名などを6文字以内に制限していたものがあり、そのために古いプログラムで識別子が短く制限されていたという事実もある。後発のプログラミング言語および処理系でも、識別子の長さに制限が設けられている場合があるが、実用的な範囲では通例問題にならない上限である。

4.2. 大文字/小文字と数字
---------------

命名規則によっては、大文字と小文字の使い方を制限しているものもある。また、大文字も小文字も使えるが、それらに意味を与える場合もある。アルファベット、数字、両方を混合した英数字の使い方を指定した命名規則もある。プログラミング言語によっては大文字と小文字を区別しないものもある。

4.3. 複数の単語からなる識別子
-----------------

一般に「意味のある識別子」が推奨される。1つの単語では意味がわかりにくい場合もあり、複数の単語を識別子に使用することになる。結果として、命名規則には、複数の単語を連結する場合の方法が指定されることになる。各プログラミング言語で定められている予約語と衝突しにくくなる効果もある。

4.3.1. 単語境界の表し方
---------------

多くのプログラミング言語は識別子内に空白を許さない。そのため、空白以外で単語の区切りを示す方法が必要となる。

区切り記号による単語の連結 英数字で記された単語を特定の区切り文字で連結する。一般に、この目的で使われる文字は、ハイフンかアンダースコアである。ハイフンはCOBOLやLISPでよく使われる。Cascading Style Sheets でもセレクタ名にハイフンが使われることが多い。他の言語はハイフンが引き算の記号と同じであるため、識別子には使わないのが一般的である。区切り文字で連結された文字列が蛇や鎖のように見えることから、スネークケースやチェーンケースと呼ばれることもある。 大文字/小文字による単語の切り分け 単語の頭文字を大文字、それ以外を小文字にする。例えば、//two words// は twoWords や TwoWords と記述される。これをキャメルケースなどと呼ぶこともある。アッパーキャメルはPascalで利用されていた経緯から、パスカルケースと呼ばれることもある。

5. メタデータと命名規則
-------------

命名規則によっては、特定のプロジェクトや問題領域に必要とされる規則や必要条件というだけでなく、ソフトウェアアーキテクチャによって定義される原則、根底にあるプログラミング言語やプロジェクト横断的な方法論などを表す大きな枠組みを提供する。

COMインターフェイス名のI接頭辞など、フレームワークによってルールが定められているものもある。

5.1. ハンガリアン記法
-------------

最もよく知られている命名規則としてハンガリアン記法  がある。これには、「目的」を名前に含める方式と、「データ型」を名前に含める方式に分けられる。

5.2. 桁位置に意味を持たせる記法
------------------

非常に短い長さで識別子を形成する場合、桁位置ごとに意味を持たせることがある。例えば、LCCIIL01 という名前で、先頭の LC は「信用状、次の C は COBOL、IIL は 特定のプロセスサブセットを表し、01 がシーケンス番号となっている。

このような規則はメインフレームでのJCLなどで今でも使われている。また、MS-DOSでのファイル名でも見られる。

5.3. 単語連結法 
------------------------

初期の命名規則として、IBMが1980年代にIMSのマニュアルで採用した "OF Language" があるdate=2008年2月}}。

これは、PRIME-MODIFIER-CLASSの形式で、例えば "CUST-ACT-NO" という名前で "customer-account-number"を表す。

PRIMEの単語は、システムが対象とする主な実体を指す。MODIFIERの単語は、補助的な具体化をしたり、可読性を向上させる役目を持つ。CLASSの単語は理想的にはデータ型を表す短いリストである。典型的なCLASS単語として、NO、ID、TXT、AMT、QTY、FL、CD、Wなどがある。実際、CLASS単語としては2ダースほどの単語がリストアップされている。

CLASS単語は一般に右端に置かれ、ハンガリアン記法の接頭辞と同じ役目を果たしている。

CLASS単語の目的は、一貫性を保つだけでなく、プログラマにデータフィールドのデータ型を指示する意味がある。BOOLEANが登場するまでは、FLが二値だけをとるフィールドを示していた。

6. 言語固有の命名規則
------------

6.1. C/C++
----------

C言語とC++はともに大文字/小文字を区別する言語だが、キーワードや標準ライブラリの識別子の多くは小文字である。C++の設計者Bjarne Stroustrupは、言語組み込みの型および標準ライブラリの型と、ユーザー定義の型を区別できるように、ユーザー定義の型の名前は大文字で始めることを推奨している。また、すべての文字を大文字にした名前は、慣例的にプリプロセッサマクロでの使用に予約されているので、マクロシンボルではない識別子の名前には絶対に使用してはいけないと助言している。

C言語の場合、次の名前が実装系のために予約されている。

グローバルスコープを持ち、_で始まる名前
_で始まり、その次が大文字の名前
__で始まる名前C++の場合、次の名前が実装系のために予約されている。

グローバルスコープを持ち、_で始まる名前
_で始まり、その次が大文字の名前
__を含む名前予約された名前をユーザー定義の識別子に利用した場合は未定義動作となるため、ユーザー定義の識別子に使ってはならない。

6.1.1. ライブラリおよびプロジェクト固有の命名規則
----------------------------

C言語は名前空間をサポートしないため、代わりに各種APIの関数や型、定数シンボルには固有の接頭辞を付けて、衝突を防いだり判別しやすくしたりすることがある。

定数名を表す際に、数学や自然科学などにおける定数のアナロジーから、k接頭辞を用いるルールも存在する。

6.2. Smalltalk
--------------

Smalltalkでは、大域変数)は大文字からはじまるキャメルケース、局所変数、メンバーとなる変数は小文字からはじまるキャメルケースを使用する。これは、言語仕様でも決まっており、存在しない大文字で始まる変数を参照するコードを書いても翻訳時にエラーとはならないが、存在しない小文字の変数を参照するコードを書いていると翻訳時にエラーとなる。また、メソッドが存在するセレクターは、小文字で始まるキャメルケースを使い、メソッドが存在しないセレクターには大文字で始まるキャメルケースを用いることが慣習になっている。これは、名前空間の解決等でメソッドが存在しないセレクターを使おうとした時、基底クラス等にメソッドが存在するとメソッドを呼んでしまうためである。後発のJavaなどはこの規則を強く継いでいる。ただし、Smalltalkにはプリプロセッサは存在しないため、全部大文字の識別子を使う慣習は存在しない。

6.3. Java
---------

Javaでは、言語仕様および標準ライブラリの設計時点から、クラスやメソッド、定数や変数などの命名における大文字/小文字の使い分けといった規則が決められている。例えば、クラス名は大文字で始める 、メソッド名や変数名は小文字で始める 、また定数名はすべて大文字でアンダースコア区切りとする、などである。

JavaBeansからの影響を発端として、特定の接頭辞を付けたアクセッサメソッド  が定義され、カプセル化に利用されることも多い。 class SomeWidget { private String caption; private boolean visible;

public String getCaption { return this.caption; } public void setCaption { this.caption = caption; } public boolean isVisible { return this.visible; } public void setVisible { this.visible = visible; } }<WtXmlEndTag />

なお、Java 9ではアンダースコア1文字の識別子_は予約済みのキーワードとなったため、ユーザーコードで識別子として使用することはできなくなった。

6.4. BASIC、Visual Basic、VB.NET
------------------------------

BASICは、C言語と違って大文字/小文字の区別をしない言語である。処理系は大文字/小文字の違いを無視してシンボルの識別をしている。これはVisual Basic  およびVisual Basic .NETにおいても受け継がれている。したがって、例えば form.show, Form.Show, FORM.SHOW はすべて同じ意味になる。ただし、識別子名は人間にとって読みやすいほうが好ましいため、VB/VB.NETでは通例シンボルの宣言時に大文字/小文字を使い分け、シンボルを利用する際も宣言に応じて区別する命名規則が採用される。型名やメソッド名、プロパティ名は大文字で始めるアッパーキャメルが採用されている。

かつてVB/VBAでは、GUI要素などの変数名に、略語の接頭辞を使う命名規則が推奨されていたが、VB.NET  ではそのようなガイドラインは存在せず、ハンガリアン記法は非推奨となっている。

6.5. Delphi 
---------------------------

Delphi言語は、PascalおよびVB系の言語と同様、大文字/小文字の区別を行なわないが、下記の命名規約が推奨されている。

レコード型、オブジェクト型、クラス型、およびtypeキーワードによる型のエイリアスなど、型を表すシンボルは'T'で始める。
インターフェイス型名は'I'で始める。
クラスのフィールド名は'F'で始める。
ルーチン名、メソッド名は大文字で始めて、大文字で単語を区切る。

6.6. C#
-------

C#言語および.NET Frameworkは、もともとDelphiの文法や言語機能およびVCLがベースになっていることもあり、Microsoftによる標準的な命名規約もDelphiに似たものを踏襲している。

C#はC/C++やJava同様に大文字/小文字を区別するが、VB.NETを始めとする他の言語との相互運用性の観点から、大文字/小文字の違いしかないシンボル群をAPI外部に公開することは避けるべきとされている。

7. 脚注
-----

8. 関連項目
-------

識別子
名前空間

9. 外部リンク
--------

[1] ThinkIT、2005年9月7日。
[2] ITpro
[3]カテゴリ:プログラミング