この文書は主に、Delphi 開発者がプログラミング時に従うべき一貫した形式を持てるように、ソース コードの記述標準とプログラムとファイルの命名標準を提供することを目的としています。このようにして、各プログラマーは他の人が理解できるコードを作成します。
インデントとは、各レベル間の 2 つのスペースを意味します。ソース コードにタブ文字を配置しないでください。これは、タブ文字の幅が設定やコード管理ユーティリティ (印刷、ドキュメント、バージョン管理など) によって異なるためです。
[ツール] | [環境] メニューを使用して、[環境オプション] ダイアログ ボックスの [全般] ページで、[タブ文字を使用する] および [オプションの塗りつぶし] チェック ボックスをオフにして、タブ文字が保存されないようにします。
余白は 80 文字に設定されます。ソースコードは通常、単語を書いてもマージンを超えることはありませんが、このルールはより柔軟です。可能な限り、1 行より長いステートメントはカンマまたは演算子で囲む必要があります。改行の後は 2 文字分インデントする必要があります。
begin ステートメントは単独の行になければなりません。たとえば、以下の最初の行は間違っていますが、2 行目は正しいです。
for i:=0 to 10 do begin // 間違っています。begin と for は同じ行にあります
for i:=0 to 10 do // はい、別の行から始めます
始める
このルールの特殊なケースは、begin が else ステートメントの一部である場合です。次に例を示します。
if 何らかのステートメント = then
始める
。
終わり
そうでなければ始まる
その他のステートメント。
終わり;
注: end ステートメントは常に別の行に記述されます。 begin が else ステートメントの一部ではない場合、対応する end ステートメントは begin ステートメントと同じ量だけインデントされます。
通常は「{...}」タイプのブロック コメントを使用します。以前の「(*...*)」タイプのブロック コメントは、未使用のコードを一時的にコメントアウトするために使用されます。Delphi 2 からは、「//」行がサポートされます。 Delphi 2.0 より前のバージョンをサポートしない場合は、「//」コメントを使用できます。
左括弧と次の文字の間にスペースはありません。同様に、右括弧と前の文字の間にスペースはありません。次の例は、正しい空白文字と間違った空白文字を示しています。
CallPRoc( Aparameter ); // エラー!
CallProc(Aparameter); // 正解です。
ステートメントに余分な括弧を含めないでください。ソースコードでは、括弧は本当に必要な場合にのみ使用されます。次の例は、正しい使用法と誤った使用法を示しています。
if (I=42) then // エラー、括弧は冗長です
if (I=42) or (J=42) then // 正しい、括弧を使用する必要がある
Object Pascal 言語の予約語とキーワードは常に完全に小文字です。以下は、Delphi 5 の予約語のリストです。
そして | 配列 | として | アズム |
始める | 場合 | クラス | 定数 |
コンストラクタ | デストラクター | ディスパッチインターフェース | ディビジョン |
する | まで | それ以外 | 終わり |
を除外する | 輸出 | ファイル | ファイナライズ |
ついに | のために | 関数 | 後藤 |
もし | 実装 | で | 継承された |
初期化 | 列をなして | インタフェース | は |
ラベル | 図書館 | モッド | なし |
ない | 物体 | の | または |
外 | 詰め込まれた | 手順 | プログラム |
財産 | 上げる | 記録 | 繰り返す |
リソース文字列 | セット | シュル | シュル |
弦 | それから | スレッド変数 | に |
試す | タイプ | ユニット | それまで |
用途 | 変数 | その間 | と |
クソ | プライベート | 保護された | 公共 |
出版された | 自動化された |
プロシージャ名は大文字で始まり、読みやすくするために互い違いに配置する必要があります。以下は間違った書き方です。
プロシージャこれは不適切な形式のルーチン名です。
これを次のように変更するだけです。
プロシージャ ThisIsMuchMoreReadableRoutineName;
可能な限り、同じタイプのパラメータをグループ化する必要があります。
プロシージャ Foo(Param1,Param2,Param3:Imteger;Param4:string);
仮パラメータの順序は主にレジスタ呼び出し規則に依存します。最も一般的に使用されるパラメータは、使用頻度の順に左から右に並べた最初のパラメータです。入力パラメータは出力パラメータよりも前に置かれます。範囲が広いパラメータは、範囲が狭いパラメータの前に配置する必要があります。例えば:
SomeProc(惑星、大陸、国、州、都市)。
一部は例外です。たとえば、イベント処理中に、TObject 型の Sender パラメータが最初に渡されるパラメータとなることがよくあります。
レコード、配列、短い文字列、またはインターフェイス型のパラメータがプロシージャによって変更されないようにするには、仮パラメータを Const とマークする必要があります。このようにして、コンパイラーは最も効率的な方法でコードを生成し、渡されたパラメーターが不変であることを保証します。
他のタイプのパラメータがプロシージャによって変更されることが予想されない場合は、それらのパラメータを Const とマークすることもできます。これは効率には影響しませんが、プロシージャの呼び出し元により多くの情報が提供されます。
ローカル変数はプロシージャ内で使用されます。必要に応じて、変数はプロシージャの開始時にすぐに初期化する必要があります。ローカルの AnsiString 型変数は空の文字列に自動的に初期化され、ローカル インターフェイスおよびディスパッチ インターフェイス型の変数は自動的に nil に初期化され、ローカルの Variant および OleVariant 型変数は自動的に Unassigned に初期化されます。
グローバル変数の使用は一般に推奨されません。ただし、それが必要な場合もあります。それでも、グローバル変数は必要な環境に限定する必要があります。たとえば、グローバル変数は、ユニットの実装部分に対してのみグローバルである場合があります。
多くのユニットで使用されるグローバル データは、共通のユニットに移動し、すべてのオブジェクトで使用する必要があります。グローバル データは、宣言時に値に直接初期化できます。すべてのグローバル変数は自動的にゼロで初期化されるため、グローバル変数を 0、nil、または Unassigned などの null 値に初期化しないでください。ゼロで初期化されたグローバル変数は、.EXE ファイル内でスペースを占有しません。ゼロで初期化されたデータは仮想データ セグメントに格納され、仮想データ セグメントはアプリケーションの起動時にのみメモリを割り当てます。ゼロ以外に初期化されたグローバル データは、.EXE ファイル内のスペースを占有します。
型識別子は予約語であり、すべて小文字にする必要があります。 Win32 API タイプは多くの場合すべて大文字で、Windows.pas またはその他の API ユニットの特定のタイプ名の規則に従います。他の変数名の場合は、最初の文字を大文字にし、他の文字は大文字と小文字を交互に使用する必要があります。以下にいくつかの例を示します。
変数
MyString: 文字列; // 予約語
WindowsHandle: HWND; // Win32 API タイプ
I: 整数; // システムユニットに導入されたタイプ識別子
Real 型は古い Pascal コードとの互換性のためだけに予約されているため、使用しないことをお勧めします。通常、浮動小数点数には Double を使用する必要があります。 Double はプロセッサによって最適化でき、IEEE によって定義された標準データ形式です。 Extend は、Double よりも広い範囲が必要な場合に使用できます。 Extend は Intel 固有のタイプであり、Java ではサポートされていません。浮動小数点変数の物理バイト数が重要な場合 (おそらく、DLL を作成するために別の言語を使用する場合)、Single を使用する必要があります。
通常、Variant と OleVariant の使用は推奨されません。ただし、データ型が実行時のみに分かる場合 (COM やデータベース アプリケーションの場合が多い)、プログラミングにはこれら 2 つの型が必要です。 ActiveX コントロールの自動化などの COM プログラミングを行う場合は OleVariant を使用し、非 COM プログラミングの場合は Variant を使用する必要があります。これは、Variant が Delphi のネイティブ文字列を効果的に保存できるのに対し、OleVariant はすべての文字列を OLE 文字列 (つまり WideChar 文字列) に変換し、参照カウント機能を持たないためです。
if/then/else ステートメントでは、最も可能性の高い実行ケースを then 節に配置し、可能性の低い実行ケースを else 節に配置する必要があります。多くの if ステートメントを避けるには、代わりに case ステートメントを使用します。レベルが 5 つを超える場合は、if ステートメントを使用しないでください。代わりに、より明確な方法を使用してください。 if ステートメントでは余分な括弧を使用しないでください。
if ステートメントでテストする条件が複数ある場合は、計算の複雑さの順に右から左に並べる必要があります。これにより、コードはコンパイラの短絡推定ロジックを最大限に活用できるようになります。たとえば、Condition1 が Condition2 よりも高速で、Condition2 が Condition3 よりも高速な場合、if ステートメントは通常次のように構築する必要があります。
条件 1 と条件 2 と条件 3 の場合、
Condition3 が False である可能性が高い場合は、短絡推定ロジックを使用して、Condition3 を先頭に置くこともできます。
条件 3 と条件 1 と条件 2 の場合、
case ステートメント内の各 case の定数は、数値またはアルファベット順に配置する必要があります。各状況のアクション ステートメントは短く、通常はコードが 4 ~ 5 行以内である必要があります。アクションが複雑すぎる場合は、コードを別のプロシージャまたは関数に配置する必要があります。 Case ステートメントの else 節は、デフォルトのケースまたはエラー検出にのみ使用されます。
Case ステートメントは、通常のインデントと命名規則に従います。
while ループを終了するために Exit プロシージャを使用しないことをお勧めします。必要に応じて、ループ条件を使用してループを終了する必要があります。 while ループを初期化するすべてのコードは while エントリの前に配置する必要があり、無関係なステートメントで区切るべきではありません。ビジネスのための補助的な作業は、サイクルの直後に実行する必要があります。
ループ数が決まっている場合は、while 文の代わりに for 文を使用する必要があります。
repeat ステートメントは while ループに似ており、同じルールに従います。
with ステートメントは注意して使用する必要があります。特に with ステートメント内で複数のオブジェクトまたはレコードを使用する場合は、with ステートメントの過度の使用を避けてください。例えば:
Record1,Record2 を使用して行う
このような状況では、プログラマが混乱しやすくなり、デバッグが困難になる可能性があります。
with ステートメントも、この章の名前付けとインデントに関する規則に従います。
例外処理は主にエラーを修正し、リソースを保護するために使用されます。これは、リソースが割り当てられている場合はどこでも、リソースが確実に解放されるように try...finally を使用する必要があることを意味します。ただし、ユニットの最初/最後の部分、またはオブジェクトのコンストラクター/デストラクターでリソースが割り当て/解放される場合は例外となります。
可能であれば、各リソース割り当ては try...finally 構造と一致する必要があります。たとえば、次のコードはエラーを引き起こす可能性があります。
SomeClass1 := TSomeClass.Create;
SomeClass2 := TSomeClass.Create;
試す
{ コードを実行する }
ついに
SomeClass1.無料。
SomeClass2.無料。
終わり;
上記のリソース割り当ての安全な解決策は次のとおりです。
SomeClass1 := TSomeClass.Create;
試す
SomeClass2 := TSomeClass.Create;
試す
{ コードを実行する }
ついに
SomeClass2.無料。
終わり;
ついに
SomeClass1.無料。
終わり;
例外が発生したときに何らかのタスクを実行したい場合は、try...excel を使用できます。通常、単にエラー メッセージを表示する場合を除き、try... を使用する必要はありません。これは、アプリケーション オブジェクトがコンテキストに基づいて自動的にこれを行うことができるためです。句でデフォルトの例外処理をアクティブ化する場合は、例外を再度トリガーできます。
処理する準備ができていない例外を含むすべての例外がブロックされるため、else 句とともに try...Except を使用することはお勧めできません。
プロシージャと関数の名前は意味のあるものでなければなりません。アクションを実行するプロセスの名前の前に、そのアクションを表す動詞を付けるのが最善です。例えば:
プロシージャ FormatHardDrive;
入力パラメータ値を設定するプロシージャの名前には、次のように Set という接頭辞を付ける必要があります。
プロシージャ SetUserName;
値を取得するプロシージャの名前には、次のように Get という接頭辞を付ける必要があります。
関数 GetUserName:string;
すべての仮パラメータの名前は、その目的を表す必要があります。必要に応じて、仮パラメータの名前の前に文字 a を付けることが望ましいです。次に例を示します。
プロシージャ SomeProc(aUserName:string; aUserAge:integer);
接頭辞 a は、パラメーター名がクラス属性またはフィールドと同じ名前を持つ場合に必要です。
2 つのユニットに同じ名前のプロシージャが含まれている場合、そのプロシージャが呼び出されると、Uses 句の後ろにあるユニット内のプロシージャが実際に呼び出されます。これを回避するには、次のようにメソッド名の前に目的のユニット名を追加します。
SysUtils.FindClose(SR);
または Windows.FindClose(Handle);
変数の名前はその目的を表す必要があります。ループ制御変数は、I、J、K などの 1 文字であることがよくあります。 UserIndex など、より意味のある名前を使用することもできます。ブール変数名は、True 値と False 値の意味を明確に示す必要があります。
ローカル変数は、他の変数の命名規則に従います。
グローバル変数は大文字の「G」で始まり、他の変数の命名規則に従います。
列挙型名は列挙の目的を表す必要があります。これがデータ型であることを示すために、名前の前に文字 T を付ける必要があります。列挙型の識別子リストのプレフィックスには、相互に関連付けるために 2 ~ 3 個の小文字が含まれている必要があります。例えば:
TSongType=(stRock、stClassical、st Country、stAlternative、stHeavyMetal、stRB);
列挙型の変数インスタンスの名前は型と同じですが、接頭辞 T が付きません。変数に、FavoriteSongType1、FavoriteSongType2 などのより特別な名前を付けることもできます。
配列型名は配列の目的を表す必要があります。タイプ名の先頭には文字「T」を付ける必要があります。配列型へのポインターを宣言する場合は、配列型の先頭に文字 P を付けて、型宣言の前に宣言する必要があります。例えば:
タイプ
PCycleArray = ^TCycleArray;
TCycleArray=整数の配列[1..100];
実際、配列型の変数インスタンスの名前は型と同じですが、接頭辞「T」が付いていません。
レコード タイプ名は、レコードの目的を表す必要があります。型名には先頭に文字 T を付ける必要があります。レコード型へのポインターを宣言する場合は、先頭に文字 P を付けて、型宣言の前に宣言する必要があります。例えば:
タイプ
P従業員 = ^T従業員;
T従業員=レコード
従業員名: 文字列;
従業員率: 2 倍。
終わり;
クラスの名前は、クラスの目的を表す必要があります。通常、クラス名の前に文字「T」を追加し、インターフェイス クラスの場合はクラス名の前に「I」を追加し、エラー例外クラスのクラス名には「E」を追加する必要があります。クラス参照型 (クラス参照型) はクラス名の前に追加する必要があります。名前の後に「Class」を追加します。例えば:
タイプ
TCustomer = クラス(TObject);
ICustomer = インターフェイス;
TCustomerClass = TCustomer のクラス
ECustomerException = クラス(例外);
クラスのインスタンス名は通常、接頭辞「T」を除いたクラス名と同じです。
変数
顧客: T顧客;
注: コンポーネントの名前については、「コンポーネント タイプ」を参照してください。
フィールドの命名は、これがフィールドであることを示すために接頭辞 F が追加されることを除いて、変数と同じ規則に従います。
すべてのフィールドはプライベートである必要があります。クラスのスコープ外のフィールドにアクセスしたい場合は、クラス属性を使用してアクセスできます。
メソッドの命名は、プロシージャや関数と同じルールに従います。
静的メソッドは、メソッドが派生クラスによってオーバーライドされたくない場合に使用する必要があります。
派生クラスによってメソッドをオーバーライドしたい場合は、仮想メソッドを使用する必要があります。クラス メソッドが複数の派生クラスによって直接または間接的に使用される場合は、動的メソッド (動的) を使用する必要があります。たとえば、クラスに頻繁にオーバーライドされるメソッドが含まれており、派生クラスが 100 個ある場合、そのメソッドを動的として定義する必要があります。これにより、メモリのオーバーヘッドが削減されます。
クラスがインスタンスを作成する場合は、抽象メソッドを使用しないでください。抽象メソッドは、インスタンスを作成しない基本クラスでのみ使用できます。
すべてのプロパティ アクセス メソッドは、クラスのプライベートまたは保護された部分で定義する必要があります。プロパティ アクセス メソッドは、プロシージャや関数と同じルールに従います。読み取りに使用されるメソッドには「Get」という接頭辞が付けられ、書き込みに使用されるメソッドには「Set」という接頭辞が付けられ、プロパティの型と同じ型の Value というパラメータが必要です。例えば:
TSomeClass = クラス(TObject)
プライベート
fsomeField: 整数;
保護された
関数 GetSomeField: 整数;
プロシージャ SetSomeField(値: 整数);
公共
property SomeField: 整数 読み取り GetSomeField 書き込み SetSomeField;
終わり;
必須ではありませんが、書き込みアクセス メソッドを使用してプライベート フィールドを表すプロパティにアクセスすることをお勧めします。
プロパティはプライベート フィールドへのアクセサーとして機能し、接頭辞 F がないことを除き、フィールドと同じ命名規則に従います。プロパティ名は動詞ではなく名詞である必要があります。プロパティはデータであり、メソッドはアクションです。配列プロパティ名は複数形にする必要がありますが、一般プロパティは単数形にする必要があります。
コンポーネントの命名はクラスの命名と似ていますが、他のコンポーネント名と競合する場合は、会社、個人、またはその他のエンティティを識別するために 3 文字の接頭辞を追加できる点が異なります。たとえば、クロック コンポーネントは次のように宣言できます。
TddgClock = クラス(TComponent)
プレフィックスの 3 文字は小文字である必要があることに注意してください。
コンポーネント インスタンスの名前は、その実際の意味を説明できるものでなければなりません。ここでの命名規則では、修正されたハンガリー語の接頭辞命名規則が使用されます。サフィックスの代わりにプレフィックスを使用する理由は、コンポーネントのタイプを検索するよりも、オブジェクト インスペクターやコード エクスプローラーでコンポーネントの名前を検索する方が簡単だからです。この標準では、コンポーネント インスタンス名は、プレフィックスと属性識別子の 2 つの部分で構成されます。
コンポーネントのプレフィックスは、ほとんどの場合、コンポーネント タイプの省略形です。以下の表のコンポーネントのプレフィックスを参照してください。
コンポーネントクラス名 | コンポーネントのプレフィックス |
TActionList、TAction はアクションのリスト項目を表します | 活動 |
TButton、TSpeedButton、TBitBtn、およびその他のボタン クラス | ボタン |
TCheckBox、TDBCheckBox、その他のチェックボックス | チェック |
TRadioButton ラジオ ボタン クラス | ルド |
TToolBar ツールバー | TB |
TMainMenu のすべてのメイン メニュー クラス | mm |
TMainMenuItem のすべてのメニュー項目クラス | 私 |
TPopupMenu のすべてのポップアップ メニュー クラス | 午後 |
TPopupMenuItem のすべてのポップアップ メニュー項目クラス | 午後 |
TLabel、TStaticText、および表示に使用されるその他のラベル クラス | ポンド |
TPanel およびその他のパネル クラス | nnl |
TPageControl およびその他のページ コントロール クラス | PGC |
TEdit、TMaskEdit、およびその他の単一行エディット ボックス クラス | EDT |
TMemo、TRichEdit、およびその他の複数行編集ボックス クラス | mmo |
TDrawGrid、TStringGrid、およびその他のグリッド クラス | グリッド |
Tanimate およびその他のアニメーション クラス | アニ |
TImageList およびその他の画像リスト クラス | イル |
TImage およびその他の画像クラス | 画像 |
TChart チャート クラス | チャット |
TComboBox、TDBComboBox、およびその他のドロップダウン リスト ボックス クラス | CB |
TListBox、TDBList、およびその他のリスト ボックス クラス | 最初の |
Tツリービュー | テレビ |
TListView | レベル |
Tホットキー | 香港 |
TSplitter およびその他の区切り文字クラス | spt |
TOpenDialog などのすべてのダイアログ コンポーネント クラス | ダウンロード |
TTable などのすべてのデータ テーブル クラス | テーブル |
TQuery などのすべての SQL クエリ コンポーネント | 質問 |
TClientDataSetAll クライアント データ セット要素 | CD |
Tデータソース | DS |
Tデータベース | データベース |
TSockConnection、TDCOMConnection、およびその他の接続コンポーネント クラス | 詐欺 |
TQuickRep、TFastReport、およびその他のレポート コンポーネント クラス | RPT |
TDDEClientConv、TDDEClientItem、およびその他の DDE コンポーネント クラス | でした |
TMonthCalendar などのすべてのカレンダー クラス | カロリー |
TGroupBox およびその他のコントロール クラス | グループ |
上に示したように、コンポーネント タイプのプレフィックスは、コンポーネントを説明するタイプ プロパティの分析から得られます。通常、次のルールはコンポーネント タイプのプレフィックスを定義する方法を説明します。
注: コンポーネントのプレフィックスは、コンポーネントがボタンであるか、ラベルであるかなど、コンポーネントのタイプを示すものであるため、特殊なコンポーネント クラスごとにコンポーネント プレフィックスを作成する必要はありません。 TMyButton はまだボタンです。
コンポーネントのプロパティ識別名は、コンポーネントの意図を説明したものです。たとえば、フォームを閉じるために使用される TButton コンポーネント インスタンスには btnClose という名前を付けることができます。編集名コンポーネントのインスタンスには、edName という名前を付けることができます。
フォームまたはダイアログ タイプの名前は、フォームの目的を表し、フォームの場合は「Tfrm」、ダイアログ ボックスの場合は「Tdlg」という接頭辞を付け、その後に説明的な名前を付ける必要があります。たとえば、About フォームのタイプ名は次のようになります。
TfrmAbout = クラス(TForm)
メインフォームの型名は次のとおりです。
TfrmMain = クラス(TForm)
顧客ログインフォームのタイプ名は次のとおりです。
TfrmCustomerEntry = クラス(TForm)
ログイン ダイアログ ボックスのタイプ名は次のとおりです。
TdlgLogin = クラス(TForm)
フォーム インスタンスの名前は、対応する型名と同じですが、接頭辞 T が付きません。たとえば、前述のフォーム タイプとインスタンスの名前は次のとおりです。
型名 | インスタンス名 |
Tfrmについて | fromについて |
TfrmMain | フロムメイン |
TfrmCustomerEntry | frmCustomerEntry |
Tdlgログイン | dlgログイン |
特別な理由がない限り、メインフォームのみが自動生成されます。他のすべてのフォームは、[プロジェクト オプション] ダイアログ ボックスで自動生成されるリストから削除する必要があります。詳細については、次のセクションを参照してください。
すべてのフォーム ユニットには、フォームの作成、設定、モーダル表示、解放のためのインスタンス化関数が含まれている必要があります。この関数は、フォームによって返されたモード結果を返します。この関数に渡されるパラメータは、パラメータ渡しの規則に従います。このようにカプセル化する理由は、コードの再利用とメンテナンスを容易にするためです。
フォームの変数はユニットから削除され、フォームのインスタンス化関数でローカル変数として定義される必要があります (これには、[プロジェクト オプション] ダイアログ ボックスで自動生成されたリストからフォームを削除する必要があることに注意してください。前の内容を参照してください。)
たとえば、次のユニット ファイルは GetUserData インスタンス化関数を示しています。
ユニットUserDataFrm;
インタフェース
用途
ウィンドウ、メッセージ、SysUtils、クラス、グラフィックス、コントロール、フォーム、
ダイアログ、StdCtrls;
タイプ
TfrmUserData = クラス(TForm)
edtユーザー名: TEdit;
edtUserID: TEdit;
プライベート
{プライベート宣言}
公共
{公的宣言}
終わり;
function GetUserData(var aUserName: String;var aUserID: Integer): Word;
実装
{$R *.DFM}
function GetUserData(var aUserName: String;var aUserID: Integer): Word;
変数
frmUserData: TfrmUserData;
始める
frmUserData := TfrmUserData.Create(アプリケーション);
frmUserData.Caption:='ユーザー データの取得';
結果 : = frmUserData.ShowModal;
結果=mrOKの場合
始める
aユーザー名 := frmUserData.edtUserName.Text;
aUserID := StrToInt(frmUserData.edtUserID.Text);
終わり;
ついに
frmUserData.Free;
終わり;
終わり;
終わり。
フォームの構造が複雑すぎる場合は、メイン フォーム フレームと、メイン フォーム フレームに埋め込まれたいくつかのサブフォーム フレームに分割する必要があります。のように:
TfrmMainFrame: TfrmInfoFrame、TfrmEditorFrame
フォーム フレームを使用する主な目的は、インターフェイスとコードの再利用の問題を解決し、ユニット コードの結合性を向上させ (分割後、各フォーム フレームは独立したユニットになります)、それによってソフトウェア エンジニアリングの品質を向上させることです。インターフェイス関連のコード (再利用可能) とアプリケーション関連のコード (再利用不可) を抽出する必要があります。
データ モジュール タイプ名はその目的を表し、先頭に「Tdm」とその後にわかりやすい名前を付ける必要があります。たとえば、Customer データ モジュールのタイプ名は次のとおりです。
TdmCustomer = クラス(TDataModule)
Orders データ モジュールの型名は次のとおりです。
TdmOrder = クラス(TDataModule)
データ モジュール インスタンスの名前は、対応する型名と同じである必要がありますが、接頭辞 T は付きません。たとえば、以前のデータ モジュールのタイプとインスタンス名は次のとおりです。
型名 | インスタンス名 |
Tdm顧客 | dm顧客 |
TdmOrder | dm注文 |
すべてのソース ファイル、プロジェクト ファイル、ユニット ファイルで構造化されたファイル ヘッダー情報を使用することをお勧めします。ファイルヘッダーには少なくとも次の情報が含まれている必要があります。
{
著者による著作権@年
}
プロジェクト ファイル名はわかりやすいものにする必要があります。たとえば、『Delphi 5 Developer's Guide Bug Manager』のプロジェクト名は DDGBugs.dpr で、システム情報プログラムの名前は SysInfo.dpr です。
フォーム ファイルの名前はフォームの目的を表し、接尾辞 Frm を付ける必要があります。たとえば、About フォームのファイル名は AboutFrm.dfm で、メイン フォームのファイル名は MainFrm.dfm です。
データ モジュール ファイルの名前は、データ モジュールの役割を表し、DM サフィックスを付ける必要があります。たとえば、Customers データ モジュールのファイル名は CustomersDM.dfm です。
リモート データ モジュール ファイルの名前は、リモート データ モジュールの目的を表す必要があります。名前の後に RDM サフィックスを追加します。たとえば、Customers リモート データ モジュールのファイルは CustomersRDM.dfm と呼ばれます。
ユニット名はわかりやすいものにする必要があります。たとえば、アプリケーションのメイン フォーム ユニットは MaimFrm.pas と呼ばれます。
Interface セクションの Uses 句には、そのセクションで必要なユニットのみを含める必要があります。 Delphi によって自動的に追加されるユニット名は含めないでください。実装部分の Uses 句には、この部分に必要なユニットのみを含める必要があり、余分なユニットは含めないでください。
Interface セクションには、外部ユニットからアクセスする必要がある型、変数、プロシージャ、関数の宣言のみを含める必要があります。さらに、これらの宣言は実装セクションの前に置く必要があります。
実装部分には、このユニットのプライベート型、変数、プロシージャ、関数の実装が含まれます。
時間のかかるコードを初期化セクションに配置しないでください。そうしないと、アプリケーションの起動が非常に遅くなります。
初期化セクションで割り当てられたすべてのリソースを必ず解放してください。
フォームユニットファイルの名前は、対応するフォーム名と同じですが、プレフィックスをサフィックスに変更するだけです。たとえば、About フォームのユニット名は AboutFrm.pas です。メインフォームのユニットファイル名はMainFrm.pasです。
データモジュールユニットファイルの名前は、対応するデータモジュール名と同じです。たとえば、データ モジュール ユニットの名前は CustomersDM.pas です。
一般ユニットの名前はその目的を表し、接頭辞「u」を付ける必要があります。たとえば、実用的なデバッグ ツールのユニットの名前は uDebugUtilities.pas で、グローバル変数を含むユニットの名前は uCustomerGlobals.pas です。
ユニット名はプロジェクト内で一意である必要があることに注意してください。共通のユニット名に同じ名前を付けることはできません。
コンポーネント セルは、コンポーネントを定義するセルであることを示すために、別のパスに配置する必要があります。通常、これらはプロジェクトと同じパスには配置されません。ユニットファイル名はその内容を表現する必要があります。
コンポーネントの命名基準の詳細については、「コンポーネント タイプの命名基準」を参照してください。
コンポーネント セルには、コンポーネント パレットに表示されるコンポーネントであるプライマリ コンポーネントを 1 つだけ含めることができます。他の補助コンポーネントまたはオブジェクトも同じユニットに含めることができます。
コンポーネント登録プロセスは、コンポーネント ユニットの外に移動し、別のユニットに配置する必要があります。この登録ユニットは、すべてのコンポーネント、プロパティ エディタ、コンポーネント エディタ、ウィザードなどを登録するために使用されます。
コンポーネントの登録はデザイン パッケージで行う必要があります。したがって、登録ユニットは実行時パッケージではなく設計時パッケージに含める必要があります。登録ユニットには次のような名前を付けることをお勧めします。
xxxReg.pas
このうち、xxx 文字の接頭辞は、コンポーネントのパッケージ名や会社、個人、その他のエンティティを識別するために使用されます。たとえば、登録ユニットの名前は xxxReg.pas です。
ランタイム パッケージには、必要なユニットのみが含まれている必要があります。プロパティ エディターとコンポーネント エディターのこれらの要素は、設計時パッケージに配置する必要があります。登録ユニットも設計段階のパッケージに含める必要があります。
パッケージの命名は次のパターンに従います。
dcliiiDescvvCn.pkg —設計パッケージ
iiiDescvvCn.pkg — ランタイム パッケージ
このうち、iii は 2 ~ 3 文字の接頭辞を表します。これは、企業、個人、またはその他の識別する必要があるものを識別するために使用されます。vv は、コントロール パッケージの短い説明を表します。必要に応じて選択できます。接頭辞「dcl」は設計時パッケージを示し、この接頭辞がなければ「Cn」という文字はコンパイラのタイプとコンパイラのバージョン番号を示します。 Delphi5=D5、Delphi4=D4、CBuilder3=C3....
パッケージ名の lib または std は、それぞれこれが設計時パッケージであるか実行時パッケージであるかを示すことに注意してください。例えば:
dclrbStdComPSD5.pkg —Delphi 5 設計時パッケージ
rbStdCompsD5.pkg —Delphi 5 ランタイム パッケージ
ほとんどのコード自動書式設定ツールは、ソース プログラムの形式を再調整したり、予約語や識別子の大文字と小文字を更新したりするのに役立ちますが、バージョン管理をすでに使用している場合は、これを実行する前に行うことをお勧めします。自動コード整形ツールを簡単に使用しないでください。スペースが 1 つ増えたとしても、バージョン管理ツールはその行が変更されたとみなして、プログラム管理に変更を加えてしまいます。