トップページ - 翻訳ドキュメント - Econos - Delphi 4 開発者ガイド コーディング標準
原文:http://www.econos.de/delphi/cs.html
訳注: 独特なルールが目に付きます。翻訳してみたものの、お勧め出来るかどうかは……微妙です。
2004/09/13 0.1.0 初版
2006/04/18 0.2.0 全体的に見直し
サイト内関連リンク:Object Pascal スタイルガイド , The Delphi Bug List 日本語訳
Copyright © 1998 Xavier Pacheco and Steve Teixeira
Modifications © 1998 Econos - Stefan Hoffmeister
Version 1.1.0
29 September 1998
Republished with permission
変更されていないオリジナルバージョンは以下にあります:
この文書のほとんど全ての内容は、Xavier Pacheco と Steve Teixeira とによって作成されたオリジナルの文書を元にしています。この文書を作るために、ほんの少しの変更だけが加えられています。
この文書は Delphi 4 Developer's Guide で使用されている Delphi プログラミングのコーディング標準について述べています。少数の例外を除き、全般的にこの文書は、Borland International によって使用されているしばしば "語られない" フォーマットガイドラインに従っています。Delphi 4 Developer's Guide にこの文書を含めている目的は、開発チームがそのコーディングに対して一貫したスタイルを強制できる方法を提供することです。その目的は、チームのプログラマ全員が他のプログラマによって書かれたコードを理解できるようにすることです。これは、一貫性を持たせることによるより可読性の高いコードを作成することで達成されます。
コーディング標準に存在するであろう全てをこの文書が含んでいる訳では決してありません。しかしながら、あなたの標準を得られる程には十分な詳細を含んでいます。あなたのニーズに合わせるために、これらの標準を自由に利用・修正してください。しかしながら、Borland の開発スタッフによって使用されているこの標準からあまりかけ離れすぎないことを推奨します。私達がこれを推奨する理由は、あなたがあなたのチームに新しいプログラマを連れて来たとき、彼らがもっとも慣れていそうな標準は Borland の標準だからです。大抵のコーディング標準の文書と同じように、この文書は必要に応じて進化して行きます。そのため、最新のバージョンはオンラインで http://www.xapware.com/ddg/ にて見つけることが出来ます。[注意: これはこの文書の オリジナルで 修正されていないバージョンに適用されます。]この文書は ユーザーインターフェイス標準 を扱いません。それは別のものですが、等しく重要なトピックです。サードパーティの書籍や Microsoft の文書がその種のガイドラインを十分にカバーしているので、私達はわざわざその情報を複製するのではなく、その情報を利用可能な Microsoft Developers Network やその他の情報源を示すことにしました。
Econos の Stefan Hoffmeister によってこの文書に適用された変更は、赤く 色付けされています。この変更はオリジナル文書の文章の変更または追加であり、レイアウトや書式の変更ではありません。
インデントは 1 レベル当たり 2 個の空白文字にします。ソースファイル内にタブ文字を保存してはいけません。タブ文字は、ユーザー設定やソース管理ユーティリティ(印刷・アーカイブ・バージョンコントロール等)によって異なる幅に展開されるためです。
ツールメニューのエディタオプションの "タブ文字の使用" をオフにし、"オプティマルフィル" をオンにすることでタブ文字が保存されるのを禁止できます。
マージンは 80 文字にセットします。一般に、単語を終了させるときの例外を除いてソースはこのマージンを超えるべきではありませんが、このガイドラインは多少柔軟です。可能であれば必ず、1 行を超えるステートメントはコンマまたは演算子の後で折り返すべきです。ステートメントを折り返す場合、論理的にまとまった部分が同じインデントレベルになるようにインデントするべきです。
コメントには通常 { } のペアを使用するべきです。
もうひとつのコメント表記 (* *) は、開発時に一時的にコードを削除("コメントアウト")するときのために予約されるべきです。
// はコメントが一行の場合に限って使用するべきです。
条件定義は中括弧 - "{", "}" - と大文字の条件コマンドとで書くべきです。
コードの可読性を高めるために、各条件定義のブロックの終わりにも条件名を記述します。
これらは通常のブロックと同じ方法でインデントするべきです。
例
if ... then begin {$IFDEF VER90} raise Exception.CreateRes(SError); {$ELSE} raise Exception.Create(SError); {$ENDIF VER90} end; |
begin ステートメントはそれだけで単独の行にします。例えば以下の 1 行目は誤りで、2 行目が正解です。
for I := 0 to 10 do begin // 誤り。begin が for と同じ行にある。 for I := 0 to 10 do // 正しい。begin が別の行に書かれている。 begin |
この規則の例外として、begin ステートメントが else の一部として現れる場合には以下のように書くことも出来ます。
if some statement = ... then begin ... end else begin SomeOtherStatement; end; |
しかしながら、より好ましい書き方は以下の通りです。
if some statement = ... then begin ... end else begin SomeOtherStatement; end; |
なぜなら、begin ステートメントが対応する if ステートメントと常に同じレベルに現れるためです。
end ステートメントは常にそれだけで単独の行にします。
begin ステートメントが else の一部ではない場合、対応する end ステートメントは begin と同じレベルにインデントします。
開き括弧とその次の文字との間に空白を入れてはいけません。同じように、閉じ括弧とその前の文字との間にも空白を入れてはいけません。以下の例は、括弧に関する誤った空白の空け方と正しい空白の空け方とを示しています。
CallProc( AParameter ); // 誤り CallProc(AParameter); // 正しい |
ステートメント中に余分な括弧を含めてはいけません。ソースコード中で意図する意味を成すのに必要な場所でのみ括弧を使用するべきです。以下の例は、誤った用法と正しい用法とを示しています。
if (I = 42) then // 誤り - 余分な括弧 if (I = 42) or (J = 42) then // 正しい - 最低限の括弧 |
Object Pascal 言語の予約語とキーワードは、常にすべて小文字であるべきです。デフォルトでは文法をハイライトする IDE の機能がこれらの単語を太字で表示します。これらの単語に大文字を使用するべきではありません。
可読性を高めるために、ルーチンの名前は大文字で始まるキャメル形式にするべきです。以下は誤った手続き名の例です:
procedure thisisapoorlyformattedroutinename; |
次は適切にキャピタライズされたルーチン名の例です:
procedure ThisIsMuchMoreReadableRoutineName; |
ルーチンには処理内容を表す意味のある名前を付けるべきです。何らかのアクションを起こすルーチンには、そのアクションの動詞を前に付けます。例:
procedure FormatHardDrive; |
入力パラメータの値をセットするルーチンは先頭に Set を付けるべきです。例:
procedure SetUserName; |
値を取得するルーチンは先頭に Get を付けるべきです。例:
function GetUserName: string; |
可能であれば、同じ型の引数はひとつのステートメントにまとめるべきです。
procedure Foo(Param1, Param2, Param3: Integer; Param4: string); |
すべての引数の名前はその目的を表す意味のある名前にし、典型的にはそのルーチンに渡される識別子の名前に基づきます。適切であれば、引数の前に文字 A を置きます。例:
procedure SomeProc(AUserName: string; AUserAge: integer); |
このプレフィクス "A" は、その引数がクラス内のプロパティやフィールドの名前と同じ名前の場合のあいまいさを無くすための習慣です。
以下に示す引数の順序付けは、レジスタ呼び出しの活用に重視を置いています。
(呼び出し側によって)もっとも良く使用される引数を最初に置き、より使われない引数をその後に左から右の順に並べるべきです。
入力引数を出力引数の前に左から右の順に置くべきです。
もっとも一般的な引数から特殊な引数へと左から右の順に置くべきです。例:
SomeProc(APlanet, AContinent, ACountry, AState, ACity)
この規則の例外はイベントハンドラです。イベントハンドラの場合、TObject 型の Sender という名前の引数がしばしば最初の引数として渡されます。
レコード・配列・ShortString・インターフェイスの引数がルーチン内で変更されない場合、その引数に const を付けるべきです。これにより、それらの変更されないパラメータをもっとも効率の良い方法で受け渡すコードをコンパイラが生成することが確実になります。
その他の型の引数でも、それがルーチン内で変更されない場合には任意で const パラメータとして定義して構いません。これは効率には影響ありませんが、そのルーチンを呼ぶ人にパラメータの用途に関するより多くの情報を提供します。
使用している二つのユニットが同じ名前のルーチンを含むときにそのルーチンを呼び出すと、uses 節に最後に現れるユニットに属するルーチンが呼ばれます。uses 節に依存したこのあいまいさを避けるため、常に意図するユニット名を付けてそのメソッドを呼びます。例えば、
SysUtils.FindClose(SR); |
または
Windows.FindClose(Handle); |
変数にはその目的を表す意味のある名前を付けます。
一般にループ制御変数には I・J・K のような 1 文字の名前が付けられますが、これは例えば UserIndex のような、より意味のある名前のほうが好ましいでしょう。
Boolean 型の変数の名前は、その True と False の意味を明らかにするのに十分なほど説明的であるべきです。
変数を宣言するとき、ひとつの型に対して複数の宣言を置くべきではありません。各変数には常にそれぞれの型を指定します。例:
var i: Integer; j: Integer; |
各変数宣言の前にキーワード var を置いても構いません。例:
var i: Integer; var j: Integer; |
手続き内で使用されるローカル変数は、他のすべての変数のための使用法と命名規則とに従います。一時変数も適切に命名します。
ローカル変数の初期化が必要な場合、ルーチンの入り口の直下で行います。ローカルの AnsiString 型変数は自動的に空文字列に初期化され、ローカルの interface 型と dispinterface 型の変数は自動的に nil に初期化され、ローカルの Variant 型および OleVariant 型の変数は自動的に Unassigned に初期化されます。
グローバル変数の使用は勧められませんが、必要であれば使用しても構いません。ただし使用する場合でも、それが使用されるコンテキスト内でのみグローバルであるように維持することが推奨されます。例えば単一のユニットの実装部のスコープでのみグローバルであることなどが許されます。
複数のユニットから使用されるグローバルデータは、すべてのユニットから使用される共通のユニットに移動するべきです。
グローバルデータは var セクション内で直接初期化することが許されています。グローバルデータは自動的にゼロで初期化されることを忘れないでください。したがってグローバル変数を 0や nil、''、Unassigned といった "空の" 値で初期化しないでください。その理由のひとつは、ゼロで初期化されるグローバル変数は exe ファイル内に領域を取らないためです。ゼロで初期化されるデータはアプリケーションのスタートアップ時にメモリ内にのみ割り当てられる'仮想'データセグメント内に保存されます。ゼロ以外で初期化されるグローバルデータは exe ファイル内に領域を占めます。
グローバル変数がゼロで初期化されるという前提を明示するコメントを追加するべきです。例:
var i: Integer { = 0 }; |
予約語の型名はすべて小文字で書くべきです。Win32 API の型名は一般にすべて大文字ですので、Windows.pas やその他の API ユニット内で示されるそれぞれの型の慣例にしたがうべきです。その他の変数名は最初の文字を大文字にし、残りはキャメル形式にするべきです。例:
var MyString: string; // reserved word WindowHandle: HWND; // Win32 API type I: Integer; // type identifier introduced in System unit |
Real 型は古い Pascal コードとの後方互換性のためにのみ存在しているため、使用は勧められません。一般的な浮動小数点の目的には Double を使用してください。Double はプロセッサ命令とバスとの最適化を促す型であり、IEEE が定義する標準フォーマットでもあります。Extended は Double よりも広い範囲が必要な場合にのみ使用してください。Extended は Intel 特有の型であり、Java ではサポートされません。Single は浮動小数点変数の物理的なバイト数が重要な場合(例えば他の言語の DLL を使用するような場合)にのみ使用してください。
列挙型の名前はその列挙の目的を良く表す名前でなければいけません。それが型宣言だと分かるように、型名の 1 文字目は T にします。列挙型の各識別子は、元の列挙型の名前に関連する 2 文字または 3 文字の小文字を前に付けるようにします。例:
TSongType = (stRock, stClassical, stCountry); |
列挙型の変数のインスタンス名は、FavoriteSongType1 や FavoriteSongType2 のような具体的な名前を付ける理由がない限り、型名から 1 文字目の T を除いた名前(SongType)にします。
Variant 型および OleVariant 型の使用は一般に勧められませんが、COM や データベースなどの開発時にありがちな、実行時にしかデータ型を知ることが出来ない場合にはどうしても必要になります。オートメーションや ActiveX コントロールのような COM ベースのプログラミングには OleVariant を使用し、非 COM プログラミングには Variant を使用します。その理由は、Variant は Delphi ネイティブの文字列を(string 型と同等に)効率よく格納しますが、OleVariant はあらゆる文字列を Ole 文字列(WideChar 文字列)に変換し、参照カウンタも使用されず、常にコピーされてしまうためです。
配列型の型名はその配列の目的を良く表す名前でなければいけません。型名の 1 文字目は T にしなければいけません。配列型へのポインタを宣言する場合、1 文字目を P にし、配列型の宣言の直前で宣言しなければいけません。
type PCycleArray = ^TCycleArray; TCycleArray = array[1..100] of Integer; |
配列型のインスタンスには、型名から 1 文字目の T を除いた名前を付けます。
レコード型にはその目的を良く表す名前を付けるべきです。型名の 1 文字目は T にしなければいけません。レコード型へのポインタを宣言する場合、1 文字目を P にし、レコード型の宣言の直前で宣言しなければいけません。各要素の型宣言は、ひとつ右のレベルにインデントしても構いません。例:
type PEmployee = ^TEmployee; TEmployee = record Name: string; Rate: Double; end; |
if/then/else 文の中でもっとも起こりやすいケースを then 節に置き、より稀なケースを else 節に置くべきです。
if 文を連続して書くことは避け、可能なら代わりに case 文を使用するようにします。
if 文を 5 段階より深くネストしてはいけません。より明瞭なアプローチを考えてください。
if 文に余分な括弧を使用してはいけません。
ひとつの if 文で複数の条件をテストする場合、計算量の少ない条件から順に左から右へと並べるべきです。これによりコンパイラに組み込まれた短絡評価の恩恵を受けることができます。例えば、Condition1 が Condition2 より計算量が少なく、Condition2 が Condition3 より計算量が少ない場合、以下のようにif 文を記述するべきです。
if Condition1 and Condition2 and Condition3 then |
複数の条件をテストするとき、各条件を別々の行に書くほうが望ましい場合があります。これは特に、ひとつまたは複数の条件が長い場合にあてはまります。このスタイルを選ぶ場合、各条件が互いに揃うようにインデントします。
if Condition1 and Condition2 and Condition3 then |
通常、左から右へと読むよりも、上から下へと読むほうが簡単です。特に長く複雑な構造の場合はなおさらです。
if 文の一部が一行を超える場合、これらの行をまとめるために begin/end を使用するべきです。この規則は、1 行のコメントだけが現れる場合や、ひとつの文が折り返されて複数行にまたがる場合にも適用されます。
else 節は対応する if 節に常に揃えるべきです。
case 文中の個々の case は、数値順またはアルファベット順に並べるべきです。ユーザー定義型を使用している場合、各文をその型の定義順に従って並べます。
ある種の状況では、case 文を重要度やヒットする頻度の順に並べるほうが望ましいかもしれません。
各 case の実行文はシンプルになるようにし、一般に 4・5 行を超えるべきではありません。実行文がもっと複雑な場合、そのコードは別の手続きや関数に置くべきです。この目的にはローカル手続きやローカル関数がとても適しています。
case 文での else 節の使用はデフォルトの場合に限られるべきです。else 節では例えば例外を生成するなどして、エラー検出と前提の明文化とのために使用するべきです。
case 文の各部はインデントされなければいけません。すべての条件文を begin..end ブロック内に書くべきです。else 節は case 文に揃えます。例:
case Condition of condition: begin ... end; else { case } ... end; |
case 文の else 節には、それが case 文に属することを示すコメントを付けるべきです。
インデントと名前付けとの規則に関して、case 文はその他の構造と同じ規則に従います。
while ループを抜けるために Exit 手続きを使用することは勧められません。可能であれば、ループ条件だけを使用してループから抜けるべきです。
while ループのための初期化コードはその while ループの入り口の直前に書くべきです。その他の関係のない文によって切り離されるべきではありません。
すべての後処理はループの直後に行うべきです。
決められた回数だけコードを実行しなければならない場合、while 文の代わりにfor 文を使用するべきです。
ステップ処理(2 以上の加算・減算)が必要な場合、分かっている方のループ端から始まり終了条件まで繰り返す while 文を使用します。例:
i := AList.Count-1; while i => 0 do i := i - 2; |
repeat 文は while と似ており、同様の一般的ガイドラインに従うべきです。
with 文は十分に注意して慎重に使用するべきです。with 文の多用は避け、with 文の中で複数のオブジェクトやレコードを使用する場合は注意してください。例:
with Record1, Record2 do |
このようなコードはプログラマを混乱させるうえ、見つけ難いバグの原因となります。
インデントと名前付けとの規則に関して、with 文はこの文書で説明されている規則に従います。
例外処理はエラー訂正とリソース保護とのために頻繁に使用されるべきです。これはつまり、リソースを割り当てるのであれば、そのリソースを確実に開放するために try..finally を使用するべきだということです。この規則の例外は、リソースの割り当て/開放をユニットの initialization / finalization で行う場合と、オブジェクトの constructor / destructor で行う場合です。
可能であればリソースの割り当て毎に try..finally 構造を使用します。例えば以下のようなコードはバグの原因になる可能性があります。
SomeClass1 := TSomeClass.Create SomeClass2 := TSomeClass.Create; try { do some code } finally SomeClass1.Free; SomeClass2.Free; end; |
より安全な方法は次の通りです:
SomeClass1 := TSomeClass.Create try SomeClass2 := TSomeClass.Create; try { do some code } finally SomeClass2.Free; end; finally SomeClass1.Free; end; |
例外発生時に何らかの処理を実行したい場合にのみ try..except を使用してください。一般に、エラーメッセージを画面に表示するためだけに try..except を使用するべきではありません。なぜならそれは Application によって自動的に行われるためです。 except 節で何らかの処理を実行した後にデフォルトの例外処理を呼び出したい場合、次の例外ハンドラへの例外を再生成するために raise を使用してください。
try..except での else 節の使用は、処理してはならない例外も含めてすべての例外をブロックしてしまうため、勧められません。
クラスの型名はそのクラスの目的を良く表す名前にします。型名はそれが型宣言と分かるように文字 T を前に置かなければいけません。例:
type TCustomer = class(TObject) |
一般に、クラスのインスタンス名はクラス名から前置の T を除いた名前と一致します。例:
var Customer: TCustomer; |
クラスのフィールド名は、それがフィールドだということを表す注釈として F を前に置くことを除き、変数の命名と同じ規則に従います。
すべてのフィールドは private であるべきです。クラスの外からアクセスされる可能性があるフィールドにはプロパティを通してアクセスできるようにします。
各フィールドはそれぞれの型と共に別々の行に宣言するべきです。例:
TNewClass = class(TObject) private FField1: Integer; FField2: Integer; end; |
メソッド名は、この文書に書かれている手続き・関数のための命名と同じ規則に従います。
子クラスでオーバーライドされたくない場合に静的メソッドを使用します。
仮想メソッドは子クラスでオーバーライドされる場合に使用します。(直接または間接に)多くの子クラスが存在するクラスでのみ動的メソッドを使用するべきです。例えば、まれにオーバーライドされる一つのメソッドと 100 の子クラスとを持つクラスでは、その 100 の子クラスで使用されるメモリを節約するために、そのメソッドを dynamic にするべきです。
しかしながら、仮想メソッドの代わりに動的メソッドを使用することでメモリ要求が削減される保証はありません。さらに、リソース消費量という観点から見た場合、動的メソッドによる利益はごくわずかなものです。したがって、次ように言うことが出来ます:
通常は仮想メソッドを使用し、例外的な 状況でのみ動的メソッドを使用します。
インスタンスが作られるクラスでは抽象メソッドを使用してはいけません。インスタンスが決して作られることのない基底クラスでのみ抽象メソッドを使用してください。
すべてのアクセスメソッドは、クラス宣言の private 部または protected 部に置かなければいけません。
プロパティのアクセスメソッドの命名は、手続きや関数と同じ規則に従います。リードアクセサメソッド(読み取りメソッド)は Get を前置しなければいけません。ライトアクセサメソッド(書き込みメソッド)は Set を前置しなければいけません。書き込みメソッドの引数は Value という名前にし、その型はそれが表しているプロパティの型になります。
TSomeClass = class(TObject) private FSomeField: Integer; protected function GetSomeField: Integer; procedure SetSomeField(Value: Integer); public property SomeField: Integer read GetSomeField write SetSomeField; end; |
private のフィールドへのアクセスを提供するプロパティは、フィールド名から F を除いた名前にします。
プロパティ名は動詞ではなく名詞にするべきです。プロパティは情報を表し、メソッドは動作を表します。
配列型プロパティは複数形にし、通常のプロパティ名は単数形にするべきです。
必須ではありませんが、private のフィールドを表すプロパティへの書き込みメソッドの使用は最小限にすることが勧められます。
プロジェクトファイルは説明的な名前にします。例えば The Delphi 4 Developer's Guide Bug Manager には DDGBugs.dpr といった名前を付け、システム情報を表示するプログラムには SysInfo.dpr のような名前を付けます。
フォームファイルはそのフォームの目的を表す説明の後ろに Frm を付けた名前にます。例えば About フォームには AboutFrm.dfm という名前を付け、メインフォームには MainFrm.dfm という名前を付けます。
データモジュールには、そのデータモジュールの目的を説明する名前を付けます。名前の後ろに DM を付けます。例えば顧客データモジュール(Customers data module)には、CustomersDM.dfm のようなフォームファイル名を付けます。
リモートデータモジュールには、そのリモートデータモジュールの目的を説明する名前を付けます。名前の後ろに RDM を付けます。例えば顧客リモートデータモジュール(Customers remote data module)には CustomersRDM.dfm のようなフォームファイル名を付けます。
ユニットファイルには説明的な名前を付けます。例えばアプリケーションのメインフォームを含むユニットは、MainFrm.pas といった名前になるでしょう。
interface 部の uses 節にはその interface 部で必要とされるユニットだけが含まれるようにします。Delphi によって自動的に追加される余分なユニットはすべて削除してください。
implementation 部の uses 節にはその implementation 部で必要とされるユニットだけが含まれるようにします。余分なユニットは削除してください。
interface 部には外部のユニットからアクセスされる型・変数・手続き/関数などの前方宣言だけが含まれるようにします。外部からアクセスされない宣言は implementation 部に置きます。
ユニット内でプライベートなすべての型・変数・手続き/関数などの宣言は implementation 部に含めるべきです。
ユニットの initialization 部に時間のかかるコードを置いてはいけません。アプリケーションの初期表示をもたつかせてしまいます。
initialization 部で割り当てたすべてのリソースを確実に開放するようにしてください。
フォームに付随するユニットファイルには、対応するフォームファイルと同じ名前を付けます。例えば About フォームには AboutFrm.pas という名前を付け、メインフォームには MainFrm.pas というユニットファイル名を付けます。
データモジュールに付随するユニットファイルには、対応するフォームファイルと同じ名前を付けます。例えば顧客データモジュール(Customers data module)には CustomersDM.pas のようなユニット名を付けます。
一般的なユニットは、そのユニットの目的を良く表す名前にします。例えばユーティリティユニットには BugUtilities.pas といった名前を付け、グローバル変数を含むユニットには CustomerGlobals.pas のような名前を付けます。
プロジェクトで使用されているすべてのパッケージ間でユニット名が一意でなければならないことを忘れないでください。一般的すぎるユニット名や普通すぎるユニット名は勧められません。
コンポーネントやコンポーネントのセットを定義しているユニットをそれぞれ区別するために、コンポーネントユニットはそれぞれ別々のディレクトリに置きます。プロジェクトと同じディレクトリに置いてはいけません。ユニット名はその内容を良く表す名前でなければいけません。
注意:コンポーネントの命名に関するさらなる情報は、ユーザー定義コンポーネント のセクションを参照してください。
すべてのソースファイル・プロジェクトファイル・ユニット等には、情報通知のためのファイルヘッダを含めることが勧められます。適切なファイルヘッダは次の情報を含まなければいけません。
{ Copyright © YEAR by AUTHORS } |
通常はこのヘッダに、ユニットの目的を表す 1 行の説明と連絡方法とを追加し、例えば以下のようにします。
{***************************************************************} { } { This line describes the purpose of the unit } { } { Copyright (c) 1998 WidgetMakers, Ltd. } { contact@WidgetMakers.corp } { } { All rights reserved. } { } {***************************************************************} |
フォームの型にはそのフォームの目的を説明する名前を付けます。型定義の 1 文字目は T とし、名前をその後に続け、最後に Form を付けます。例えば About フォームの型名は以下のようにします。
TAboutForm = class(TForm) |
メインフォームの定義は以下のようにします。
TMainForm = class(TForm) |
顧客登録フォーム(customer entry form)には以下のような名前を付けます。
TCustomerEntryForm = class(TForm) |
フォームのインスタンスは、対応する型名から 1 文字目の T を除いた名前にします。例えば上記のフォームの場合、以下のようなインスタンス名にします。
型名 | インスタンス名 |
TAboutForm | AboutForm |
TMainForm | MainForm |
TCustomerEntryForm | CustomerEntryForm |
特に理由がない限り、自動生成するのはメインフォームだけにします。その他のすべてのフォームは、プロジェクトオプションのダイアログボックスにある自動生成のリストから削除してください。さらなる情報は次のセクションを参照してください。
すべてのフォームに、そのフォームを生成し、セットアップし、そのフォームをモーダル表示し、最後に開放するというインスタンス化関数を含むようにします。この関数はそのフォームの Modal Result を返します。この関数への引数は、この文書で規定されている"引数の受け渡し"の規則に従います。これはコードの再利用と保守とを容易にするためにカプセル化するための関数です。
フォーム変数はユニットから削除し、インスタンス化関数の中でローカル変数として宣言します。これを行うには、プロジェクトオプションダイアログにある自動生成のリストからそのフォームを削除する必要があることに注意してください。自動生成フォーム を参照してください。
例えば次のユニットは、ユーザーデータを取得するフォームの GetUserData 関数です。
unit UserDataFrm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TUserDataForm = class(TForm) edtUserName: TEdit; edtUserID: TEdit; private { Private declarations } public { Public declarations } end; function GetUserData(var aUserName: string; var aUserID: Integer): Word; implementation {$R *.DFM} function GetUserData(var aUserName: string; var aUserID: Integer): Word; var UserDataForm: TUserDataForm; begin UserDataForm := TUserDataForm.Create(Application); try UserDataForm.Caption := 'Getting User Data'; Result := UserDataForm.ShowModal; if Result = mrOK then begin aUserName := UserDataForm.edtUserName.Text; aUserID := StrToInt(UserDataForm.edtUserID.Text); end; finally UserDataForm.Free; end; end; end. |
DataModule の型にはそのデータモジュールの目的を説明する名前を付けます。型定義の 1 文字目は T とし、名前をその後に続け、最後に "DataModule" を付けます。例えば顧客データモジュール(Customer data module)の型名は以下のようにします。
TCustomerDataModule = class(TDataModule) |
例えば注文データモジュール(Orders data module)には以下のような名前を付けます。
TOrdersDataModule = class(TDataModule) |
データモジュールのインスタンスは、その型名から前置の T を除いた名前にします。例えば前述のデータモジュールの型の場合、以下のようなインスタンス名にします。
型名 | インスタンス名 |
TCustomerDataModule | CustomerDataModule |
TOrdersDataModule | OrdersDataModule |
実行時パッケージには、そのパッケージ内の他のコンポーネントによって必要とされるユニット/コンポーネントのみが含まれるようにします。プロパティエディタ/コンポーネントエディタやその他の設計時のみに必要なコードを含むユニットは、設計時パッケージに置くべきです。コンポーネントを登録するためのユニットは設計時パッケージに置きます。
パッケージは以下のテンプレートにしたがって命名します。
"iiilibvv.pkg" - 設計時パッケージ
"iiistdvv.pkg" - 実行時パッケージ
ここで "iii" は識別子のプレフィクスを表す 3 文字です。このプレフィクスは会社や個人や、その他の任意の要素を特定するために使用できます。
"vv" はパッケージが意図している Delphi のバージョンに対応するそのパッケージのバージョンを表しています。
実行時パッケージか設計時パッケージかを表すために、パッケージ名に "lib" または "std" を含めることに注意してください。
設計時パッケージと実行時パッケージとが両方存在する場合、ファイルは同じような名前になります。例えば Delphi 4 Developer's Guide のためのパッケージは以下のようになります。
DdgLib40.pkg - 設計時パッケージ
DdgStd40.pkg - 実行時パッケージ
プレフィクスを表す 3 文字を付けることを除き、コンポーネントは "クラス" のセクションで定義されているのと同じ規則にしたがうべきです。このプレフィクスは会社や個人や、その他の任意の要素を特定するために使用できます。 例えば Delphi 4 Developer's Guide のために書かれた時計(Clock)コンポーネントは次のように定義します。
TddgClock = class(TComponent) |
3 文字のプレフィクスを小文字で書くことに注意してください。
コンポーネントユニットは、主要なコンポーネントを一つだけ含むべきです。主要なコンポーネントとは、コンポーネントパレットに現れる任意のコンポーネントです。主要なコンポーネントと同じユニットに、任意の補助的なコンポーネント/オブジェクトを置くことが出来ます。
コンポーネントの登録手続きはコンポーネントユニットから切り離し、別のユニットに置くべきです。任意のコンポーネント・プロパティエディタ・コンポーネントエディタ・エキスパートなどを登録するために登録ユニットを使用するべきです。
コンポーネントの登録は設計時パッケージ内でのみ行われるべきです。したがって登録ユニットは実行時パッケージに含めず、設計時パッケージに含めるべきです。
登録ユニットは以下のように命名することが推奨されます。
XxxReg.pas |
ここで "Xxx" は 3 文字のプレフィクスで、会社や個人や、その他の任意の要素を特定するために使用されます。例えば Delphi 4 Developer's Guide 内のコンポーネントのための登録ユニットは DdgReg.pas のような名前にします。
すべてのコンポーネントには説明的な名前を付けなければいけません。Delphi によって付けられるデフォルトの名前は残しません。コンポーネントには型を表す小文字のプレフィクスを付けます。コンポーネントにポストフィクスではなくプレフィクスを付ける理由は、オブジェクトインスペクタやコードエクスプローラ上でコンポーネントの型による検索を容易にするためです。
以下のプレフィクスは Delphi 4 に付属している標準コンポーネントに割り当てられるものです。サードパーティ製コンポーネントによって追加されるコンポーネントをこのリストに追加してください。
プレフィクス | コンポーネント |
mm | TMainMenu |
pm | TPopupMenu |
mmi | TMainMenuItem |
pmi | TPopupMenuItem |
lbl | TLabel |
edt | TEdit |
mem | TMemo |
btn | TButton |
chk | TCheckBox |
rb | TRadioButton |
lb | TListBox |
cb | TComboBox |
scb | TScrollBar |
gb | TGroupBox |
rg | TRadioGroup |
pnl | TPanel |
cl | TCommandList |
プレフィクス | コンポーネント |
bbtn | TBitBtn |
sb | TSpeedButton |
me | TMaskEdit |
sg | TStringGrid |
dg | TDrawGrid |
img | TImage |
shp | TShape |
bvl | TBevel |
sbx | TScrollBox |
clb | TCheckListbox |
spl | TSplitter |
stx | TStaticText |
cht | TChart |
プレフィクス | コンポーネント |
tbc | TTabControl |
pgc | TPageControl |
il | TImageList |
re | TRichEdit |
tbr | TTrackBar |
prb | TProgressBar |
ud | TUpDown |
hk | THotKey |
ani | TAnimate |
dtp | TDateTimePicker |
tv | TTreeView |
lv | TListView |
hdr | THeaderControl |
stb | TStatusBar |
tlb | TToolBar |
clb | TCoolBar |
プレフィクス | コンポーネント |
tm | TTimer |
pb | TPaintBox |
mp | TMediaPlayer |
olec | TOleContainer |
ddcc | TDDEClientConv |
ddci | TDDEClientItem |
ddsc | TDDEServerConv |
ddsi | TDDEServerItem |
プレフィクス | コンポーネント |
csk | TClientSocket |
ssk | TServerSocket |
wbd | TWebDispatcher |
pp | TPageProducer |
tp | TQueryTableProducer |
dstp | TDataSetTableProducer |
nmdt | TNMDayTime |
nec | TNMEcho |
nf | TNMFinger |
nftp | TNMFtp |
nhttp | TNMHttp |
nMsg | TNMMsg |
nmsg | TNMMSGServ |
nntp | TNMNNTP |
npop | TNMPop3 |
nuup | TNMUUProcessor |
smtp | TNMSMTP |
nst | TNMStrm |
nsts | TNMStrmServ |
ntm | TNMTime |
nudp | TNMUdp |
psk | TPowerSock |
ngs | TNMGeneralServer |
html | THtml |
url | TNMUrl |
sml | TSimpleMail |
プレフィクス | コンポーネント |
ds | TDataSource |
tbl | TTable |
qry | TQuery |
sp | TStoredProc |
db | TDataBase |
ssn | TSession |
bm | TBatchMove |
usql | TUpdateSQL |
プレフィクス | コンポーネント |
dbg | TDBGrid |
dbn | TDBNavigator |
dbt | TDBText |
dbe | TDBEdit |
dbm | TDBMemo |
dbi | TDBImage |
dblb | TDBListBox |
dbcb | TDBComboBox |
dbch | TDBCheckBox |
dbrg | TDBRadioGroup |
dbll | TDBLookupListBox |
dblc | TDBLookupComboBox |
dbre | TDBRichEdit |
dbcg | TDBCtrlGrid |
dbch | TDBChart |
プレフィクス | コンポーネント |
dcb | TDecisionCube |
dcq | TDecisionQuery |
dcs | TDecisionSource |
dcp | TDecisionPivot |
dcg | TDecisionGrid |
dcgr | TDecisionGraph |
プレフィクス | コンポーネント |
qr | TQuickReport |
qrsd | TQRSubDetail |
qrb | TQRBand |
qrcb | TQRChildBand |
qrg | TQRGroup |
qrl | TQRLabel |
qrt | TQRText |
qre | TQRExpr |
qrs | TQRSysData |
qrm | TQRMemo |
qrrt | TQRRichText |
qrdr | TQRDBRichText |
qrsh | TQRShape |
qri | TQRImage |
qrdi | TQRDBMImage |
qrcr | TQRCompositeReport |
qrp | TQRPreview |
qrch | TQRChart |
ダイアログボックスは実際にはコンポーネントによってカプセル化されたフォームです。そのため、フォームの命名規則に似た規則に従います。型定義はコンポーネント名としてあらかじめ定義されています。インスタンス名は Delphi によって付けられる数字のポストフィクスを取り除き、その型と同じ名前にします。以下はその例です。
型 | インスタンス名 |
TOpenDialog | OpenDialog |
TSaveDialog | SaveDialog |
TOpenPictureDialog | OpenPictureDialog |
TSavePictureDialog | SavePictureDialog |
TFontDialog | FontDialog |
TColorDialog | ColorDialog |
TPrintDialog | PrintDialog |
TPrintSetupDialog | PrinterSetupDialog |
TFindDialog | FindDialog |
TReplaceDialog | ReplaceDialog |
プレフィクス | コンポーネント |
dbll | TDBLookupList |
dblc | TDBLookupCombo |
ts | TTabSet |
ol | TOutline |
tnb | TTabbedNoteBook |
nb | TNoteBook |
hdr | THeader |
flb | TFileListBox |
dlb | TDirectoryListBox |
dcb | TDriveComboBox |
fcb | TFilterComboBox |
プレフィクス | コンポーネント |
gg | TGauge |
cg | TColorGrid |
spb | TSpinButton |
spe | TSpinEdit |
dol | TDirectoryOutline |
cal | TCalendar |
ibea | TIBEventAlerter |
プレフィクス | コンポーネント |
cfx | TChartFX |
vsp | TVSSpell |
f1b | TF1Book |
vtc | TVTChart |
grp | TGraph |
プレフィクス | コンポーネント |
prv | TProvider |
cds | TClientDataSet |
qcds | TQueryClientDataSet |
dcom | TDCOMConnection |
olee | TOleEnterpriseConnection |
sck | TSocketConnection |
rms | TRemoteServer |
mid | TmidasConnection |
Delphi Information Resources に戻る。