メインコンテンツまでスキップ

コーディング標準

プロジェクトでのコーディング標準や規約をAIに伝えておくことは重要です。 これらの情報をインプットすることで、AIに以下のことが期待できます。

  • プロジェクトのルールに沿ったコードを生成する
  • 既存のコードとよく似たコードを生成する

このようなことは静的解析ツールでもある程度代替できますが、AIを活用する以前は人がレビューで目視や本人の判断で確認していたことも多いでしょう。
またレビューで本来確認したい、本質的な実装内容ではありません。

AIがコード生成する時にコーディング標準や規約を伝えておくことで、これらの確認の手間を軽減できるでしょう。

以下は、コーディング標準に関するインストラクションファイルの記述例です。

---
applyTo: "**"
---

# コーディング標準

このプロジェクトにおけるコーディング標準を定義します。

## Java全般的に関するルール

- クラス、メソッド、フィールドにJavadocを記載してください
- DTOやリクエスト、レスポンスのようなデータを保持することを目的にするクラスは、できる限りRecordsを使用してください
- コレクションを使用する時は、`List``Map``Set`から目的に合わせて適切なコレクションおよび実装クラスを選択してください
- 可能な限り、変数への再代入は避けイミュータブルな実装としてください

## ステレオタイプごとのルール

[クラスのステレオタイプとパッケージ構成](./stereotype.instructions.md)で定義した各クラスの責務にもとづき、以下のルールに従って実装してください。

### Controller

- HTTPリクエストをRequestとして受け取り、バリデーションを行います
- ビジネスロジックは実装せず、Serviceへ処理を委譲します
- Serviceから受け取った結果はDTOやModelからResponseに変換し、HTTPレスポンスとして返却します
- アプリケーションのトランザクション境界とし、クラス宣言に`@Transactional`アノテーションを付与します
- 参照のみの処理の場合は、メソッドに`@Transactional(readOnly =true)`を付与します
- 可変のフィールドを定義しないでください

### Request

- HTTPリクエストのパラメータをマッピングするフィールドを持ちます
- 単項目および項目間のバリデーションを、Jakarta Bean Validationを使用して実装します
- 項目間のバリデーションには`@AssertTrue`を使用します
- ControllerからServiceを呼び出す際にRequestをDTOに変換する必要がある場合は、`to[変換先のDTO名]`メソッドを定義して変換します

### Response

- HTTPレスポンスボディにマッピングするフィールドを持ちます
- Controllerからレスポンスを返却する際に、DTOからResponseに変換する必要がある場合は`static``from[変換元のDTO名名]`メソッドを定義して変換します

### Service

- アプリケーションのビジネスロジックおよびデータベースアクセスを伴うバリデーションを実装します
- データベースアクセスが必要な場合は`Mapper`を呼び出します
- 単一レコードに対する更新および削除時は、更新件数を確認し楽観的排他制御を行ってください
- メソッドの引数はJavaの基本型およびコレクション、またはDTOおよびコレクションとします
- メソッドの戻り値はJavaの基本型およびコレクション、またはDTOおよびそのコレクションとします
- 可変のフィールドを定義しないでください

### DTO

- ビジネスロジックに必要なデータをフィールドとして定義します
- ModelからDTOに変換する`static``from[変換元のModel名]`メソッドを持ち、Serviceからの戻り値として使用します

### Mapper

- データベースアクセスを行うMyBatisのインタフェースです。
- SQLはXML Mapperファイルに定義します
- メソッドに複数の引数を持つ場合であっても、`@Param`アノテーションは使用しないでください

### Model

- データベースアクセスの際のパラメータや結果をマッピングするフィールドを定義します
- JOINした結果をマッピングする際もModelとして定義します

## 例外処理

- アプリケーションから例外をスローする場合は、共通で定義された例外をスローしてください
- `try``catch`ブロックで例外をキャッチした際は、より上位の例外にラップして再スローするか、ログ出力を行ってください

## SQLおよびXML Mapperファイルに関するルール

- SQLの予約語は大文字で記述してください(例:`SELECT`, `FROM`, `WHERE`
- テーブル名やカラム名は小文字で記述してください
- `SELECT *`は使用せず、取得するカラムを明示的に指定してください
- 複雑なクエリにはコメントを追加してください
- SQLインジェクションのリスクを避けるため、`${変数名}`は使用しないでください
- `ORDER BY`などで動的にテーブル名やカラム名を指定する必要がある場合は、`choose`および`when`などの条件分岐と組み合わせて表現するようにしてください
- 単一レコードに対する`UPDATE`および`DELETE`を行う場合は、バージョンNoを使用した楽観的排他制御を行ってください

このようなインストラクションファイルを、.github/instructions/coding-standards.instructions.mdのようなファイル名で作成します。これにより、GitHub Copilotはプロジェクトの規約を理解し、より適切に開発をサポートしてくれるようになります。

実装例はインストラクションファイルに含めない

本ページを読むと、各ステレオタイプの実装例までインストラクションファイルに含めた方がよいのではないか、と考えるでしょう。
実装例自体はAIが生成するコードの精度向上には必要ですが、内容が長大になりやすくコンテキストウィンドウを圧迫します。
1回の指示で生成するコードに関わる実装例を、プロンプトに含めるのがよいでしょう。
つまり、実装例は指示内容に応じたプロンプトファイルへ含めることをお勧めします。