この文書を始めるにあたり、コーディング標準について重要と考えられる一般的概念をいくつか論じる。まず、もっとも重要なコーディング標準として推奨する「最優先規範」(2)から始め、続いて良い命名・良いドキュメントへ導く要素を述べる。この章では、以降のJavaコーディングのための標準・指針を述べていく文書のための舞台を整える。
Javaのコーディング標準がなぜ重要なのか、それは標準が自分自身や仲間が作り出すコードの間に高い一貫性をもたらすからである。一貫性が高いコードは理解がしやすい。理解しやすさは言い換えると開発容易性と保守容易性である。これはアプリケーションの開発コスト全体を低減する。
あなたが書いたJavaのコードは、あなたが他のプロジェクトへ移った後もずっと長い期間存在し続けることを忘れてはならない。開発を通じてもっとも重要な目標は、あなたの作業を他の人または開発チームに移管できることを保証することである。その結果、彼らはあなたの書いたコードを解析するという不当な労力を払わずに保守や拡張を続けることができる。理解し難いコードは、捨てられ書き直されることになる。もし皆が自分勝手にコーディングしていたら、開発者の間でコードを共有することができなくなるため、開発費用、保守費用を高騰させてしまうだろう。
経験の浅い開発者や改善の余地のないカウボーイプログラマーはしばしば標準に従うことに抵抗する。彼らは自分のやり方ならば早くコードを書けると主張するだろう。まったくナンセンスである。彼らは早くコードを仕上げると思い込んでいるが、疑わしい。カウボーイプログラマーはいくつか発見困難なバグに遭遇するとハングアップしてしまい、そして彼らの書いたコードを改良する必要が生じる度に自分の手でその大半を書き直すことになりがちである。なぜなら自分だけしか理解できないコードを書くからである。これが望むやり方だろうか?私はそうではない。
完全な標準など存在しないし、すべての状況に適用できる標準もない。大抵の場合、一つや二つは標準を適用できない状況がある。標準における最優先規範と考えるものを紹介する。
好むと好まざるとに関わらず、それぞれの標準を理解し、いつ適用すべきかを理解し、同じく重要なことはいつ適用しないべきかを理解することが必要である。
命名規約についてはこの文書を通して議論していく。そこでいくつかの基本を述べる。
例えばfirstName, grandTotal, CorporateCustomerのような命名を用いる。 x1,y1,fnのような名前は短いためタイプしやすいが、それが何を表現するかについての指標がなにもないので、結果としてコードが理解・保守・拡張困難になる(Nagler,1995; Ambler,1998a)。
もしユーザがclientsのことをcustomerと定義しているなら、そのクラスにはClientではなくCustomerと命名する。 多くの開発者は、既にその産業/分野に相応しい用語があるにもかかわらず、一般的な用語を作り出してしまう誤りをおかす。
一般的には小文字を使う。 複数の単語で一つの名前を構成するときは、名前の最初の1文字以外の単語の先頭を大文字とする。ただし、クラス名・インタフェース名については最初の1文字を大文字とする(Kanerva, 1997)。
略語を使用するときは、省略形の標準リストを作成し、賢く選び、一貫して使用すること。例えば、"number"という単語の省略形を使いたいなら、nbr, no, numから一つ選び、どれを選んだかをドキュメントし(実際どれを選ぶかは重要ではない)、それだけを使う。
クラス名PhysicalOrVirtualProductOrServiceはその時点ではよい名前に見えるかもしれないが、あまりに長すぎるので、何かより短いものに、Offeringといったような名前に変更することを考えた方がよい(NPS,1996)。
例えば、persistentObjectとpersistentObjectsとは同時に使うべきでない。 同様に、anSqlDatabaseとanSQLDatabaseとも同時に使わない(NPS,1996)。
名前にはStandard Query Languageの場合のSQLのように標準的な略語がある。属性名についてはsQLDatabaseではなくsqlDatabaseと命名し、クラス名についてはSQLDatabaseではなくSqlDatabaseと命名する方が読み易い。
ドキュメント規約についてもこの文書を通して議論していく。そこでいくつかの基本を述べる。
コードにドキュメントを書く理由は、自分自身、一緒に仕事をしている人、後に関わる開発者にとってコードをより理解しやすいものにするためである(Nagler,1995)。
Nagler氏の言は正鵠を射ている。
1960年代から1970年代の典型的なCOBOLプログラマーにはアスタリスク(*)でコメントを囲った箱を書く習慣があった。 彼らの芸術的な主張を表わしているのかもしれないが、率直に言えばそれは製品に加わるちょっとした価値に比べれば大きな時間の無駄である。かわいいコードではなくきれいなコードを書くはずである。 さらに、コードを表示するディスプレイや印刷するプリントに使われるフォントはプロポーショナルだったりそうでなかったりして、箱をきれいに整列させることは難しい。
かつて見たもっとも最良のコメントは、シンプルな要点をまとめた注釈であった。なにも本を書く必要はなく、他の人がコードを理解するに十分な情報を提供するだけでよいのである。
コードをドキュメント化する最良の方法は、コードを書く前にドキュメントすることである。 それが、コードを書く前にコードがどのように動作するかについて考えるよい機会となり、同時にコードを書く前にドキュメントされることになる。 そうでなければ、少なくともコードを書いた時にドキュメントするべきである。 ドキュメントによってコードが理解しやすくなることで、コードの開発中にアドバンテージを得ることができる。コードにドキュメントを書く時間を費やすなら、少なくともそれによって得られるものがある(Ambler,1998a)。
基本的に、コードの一部分を見ればそれが何かを理解することはできる。 例えば、以下の例1.1のコードを見て、$1000以上の注文については5%ディスカウントされることは理解できる。なぜそうなのか? 大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか? 大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか? これを書いたプログラマーの気前がよかったのか? どこかソースコード中か別な文書にドキュメントされていない限り、なぜなのかを知ることはできない。
if (grandTotal >= 1000.00) {
grandTotal = grandTotal * 0.95;
}
Javaでは3種類のコメントが使える。ドキュメント化コメントは/**で開始され、*/で終わる。C風コメントは/*で開始され*/で終わる。単一行コメントは//で開始され、そのソースコード行が終わるまで続く。以下の表では私の提案するコメントの使い方とその例の抜粋を載せる。
| コメント種類 | 使用方法 | 例 |
|---|---|---|
| ドキュメント化コメント | ドキュメント化したいinterface, class,メソッド,フィールドの直前に書く。ドキュメント化コメントはjavadocによって処理され、クラスの外部ドキュメントとして生成される。 | /** 顧客(Customer)- 顧客は われわれがサービスまたは 製品を売った人物もしくは 組織のいずれかである。 @author S.W.Ambler */ |
| C風コメント | 特定のコードを無効化したいが、後で使用するかもしれないので残しておくためにコメント化する時や、デバッグ時に一時的に無効化するときに使用 | /* このコードはJ.T.Kirkに よって1997.12.9に前述の コードと置き換えたため コメント化した。 2年間不要であるならば、 削除せよ。 ... (ソースコード) */ |
| 単一行コメント | メソッド内にて、ビジネスロジック、コードの概要、一時変数の定義等を記述 | // 1995年2月に開始された // サレク氏の寛大なキャン // ペーンで定められた通り // 1000$を超える請求には、 // 全て5%割引を適用する。 |
もっとも重要なことは、自分の組織でC風コメントと単一行コメントをどのように使うべきかの標準を決め、その標準に一貫して従うことである。ひとつをビジネスロジックのドキュメントに使い、もうひとつを古いコードのコメントアウトに使うというように。私は、コードと同じ行にドキュメントできる(インライン)という理由から、単一行コメントをビジネスロジックに使うことにしている。そしてC風コメントを古いコードのコメントアウトに使用する。なぜならば、複数行を一度にコメントアウトでき、またC風コメントはドキュメント化コメントと非常に似ているので、誤用を避けるためである。
McConnel(1993)はインラインコメント(行末コメント)の使用を強硬に反対している。それはコードの右側にきちんと揃っておかれ、コードの視覚的な構造とは干渉していない点を指摘している。その結果、フォーマット作業が大変であり、たくさん使っていればそれだけ整列作業に時間を費やすことになる。そんな時間を費やしてもコードについて理解が深まるわけではなく、ただスペースキーやタブキーを叩くくだらない作業にささげるだけである。また、行末コメントは保守が大変である点を指摘している。ある行のコードの記述が増えて行末コメントの位置を超えてしまった場合、行末コメントの位置を揃えるためには残りの行末コメントについても同じ作業をしなければならない。そうではあるが、私からのアドバイスは、行末コメントを揃えることに時間を使うなということである。
SunのJava開発キット(JDK)に含まれているjavadocと呼ばれるプログラムは、Javaコードが書かれたファイルを処理し、そのJavaプログラムについてのHTML形式の外部文書を生成する。javadocはすばらしいプログラムだが、これを書いている時点においては、いくつかの制限がある。まず第1にタグの種類が少ないことである。既存のタグは確かによいものだが、コードを適切にドキュメントするには十分とはいえない。以下にjavadocタグの簡単な概要を示す。さらに詳しく知りたい場合はJDK javadocのドキュメントを参照せよ。
| タグ | 使用対象 | 目的 |
|---|---|---|
| @author name | クラス、インタフェース | コードの該当部分の著者を示す。著者ごとに1つのタグを使う。 |
| @deprecated | クラス、インタフェース、メソッド | クラスのAPIがdeprecatedであり、今後は使うべきでないことを示す。 |
| @exception name description | メソッド | メソッドが投げる例外を記述する。例外毎に1つのタグを使い、その例外のクラス完全名を書く。 |
| @param name description | メソッド | メソッドに渡されるパラメータをその型と使用例を交えて記述する。 |
| @return description | メソッド | メソッドの戻り値について記述する。型についてと、戻り値がどのように使われるかを示す。 |
| @since | インタフェース、クラス、メソッド | この要素がいつから登場しているかを示す。すなわちsince JDK1.1 |
| @see ClassName | クラス、インタフェース、メソッド、フィールド | 文書中に指定されたクラスへのハイパーリンクを生成する。完全限定名を使えるし、使うべきである。 |
| @see ClassName#メソッド名 | クラス、インタフェース、メソッド、フィールド | 文書中に指定されたメソッドへのハイパーリンクを生成する。完全限定名を使えるし、使うべきである。 |
| @version text | クラス、インタフェース | コードの該当部分についてのバージョン情報を示す。 |
コードにドキュメントする方法は自分自身の生産性と後にコードを保守し拡張する他のすべての人との両方にとって非常に大きな影響をもたらす。開発プロセスの早期にコードにドキュメントすることで、ロジックをコードに書きとめる前に十分考えさせられるため、生産性が向上する。さらに、数日もしくは数週間前に書いたコードを見直している時にも、コードを書いていた頃に何を考えていたか容易に判る。コードに既にドキュメントされているのである。
可能な限り標準や指針を再利用し、再考案をしないこと。標準や指針の適用範囲は広ければ広いほど望ましい。工業標準は組織の標準より望ましいし、組織標準はプロジェクト標準よりも望ましい。プロジェクトは真空の中では開発できないし、組織は真空の中では運営できない。それゆえ、標準の適用範囲が大きいほど誰か他の人が後に続いてきて、ともに仕事するのが容易になるという可能性が大きくなる。
工業標準>組織標準>プロジェクト標準>個人標準>標準なし