


モジュールに分かれたJavaのプロジェクトで、互換性を壊さず小さく直す
モジュールに分かれたJavaのプロジェクトをAIに直させる時に使う。先にビルドとCIの決まりを調べ、古いJavaのバージョンとモジュールの依存関係を壊さず、合ったレベルでテストし、広い変更や壊す操作の前には聞いて止まる。
このAIルールを使うには
## 編集の前に、ビルド・書式・CIの決まりを調べる
リポジトリの指針、ビルド設定、書式規則、継続的インテグレーションのチェックを、実行可能な契約として扱う。編集前に該当する指示を読み、どの規則が機械的に強制されるかを特定する。
- 標準のビルドラッパー、フォーマッター、静的チェック、テストコマンド、貢献ポリシーを見つける。
- コードを変更する前に、担当モジュールとその依存関係をたどる。
- その場で便利な代替手段より、プロジェクトで確立されたユーティリティとパターンを優先する。
- ソース互換性、ビルドツールの要件、実行環境のサポート、配布時の動作を区別する。
- 変更を通すためだけに品質ゲートを無効にしない。
要求された動作を制御する、最小限の正本入力を使う。
## 決められたJavaのバージョンと依存関係で動くように保つ
ビルドでは新しいツールチェーンが必要でも、ソースは古い実行環境との互換性を維持している場合がある。宣言されたソースレベルに合わせてコンパイルとテストを行い、手元の環境が新しいからといって、新しい言語機能やライブラリAPIを使用できるとは考えない。
- サポートされていない便利なAPIは、互換性のある同等機能へ置き換える。
- 必要な場合は、リポジトリで再配置またはシェーディングされた依存関係の名前空間を使う。
- 検証、シリアル化、コレクション、ファイル、Future、時刻には、プロジェクト所有のユーティリティを優先する。
- 配布物が該当ライブラリを隔離している場合は、第三者ライブラリを直接インポートしない。
- 依存関係を追加する前に、互換性、ライセンス、パッケージ化、推移的な影響を検討する。
手元のコンパイルだけで済ませず、リポジトリで指定されたビルドターゲットを通じて互換性を確認する。
## 公開APIは、ファクトリーとビルダーと不変オブジェクトで作る
APIには意図した安定性を示す。安定した公開契約、発展中の公開契約、内部実装の領域を明確に区別する。
- ファクトリーからはインターフェースを返し、非公開コンストラクターまたは静的生成メソッドの背後に構築処理を隠す。
- 複数段階の設定にはビルダーを使い、流れるように記述できるメソッドと、検証を伴う単一の構築地点を設ける。
- 結果オブジェクトは、状態をfinalとして保持し、setterを持たず、等価性判定、ハッシュ値、文字列表現を完全に実装した不変オブジェクトにする。
- 呼び出し元が安全でないキャストを使わずに両方の形式を必要とする場合は、汎用インターフェースと型付きインターフェースを用意する。
- 公開型にはスレッド安全性に関する前提を記載する。
公開契約を変更するには、互換性分析と適切なバージョン管理の経路が必要になる。
## モジュールどうしの依存を一方向に保つ
実装前にモジュールグラフを把握する。基盤モジュールが共有型とインターフェースを所有し、その上にプロトコル層や転送層を構築する。同格のクライアントモジュールとサーバーモジュールを相互依存させず、統合機能は安定した下位層の上に置く。
- 共有インターフェースは適切な最下位モジュールに定義し、実装はその上位に置く。
- コネクターや任意の統合機能からコアへ依存関係を漏らさない。
- 循環依存と、同格モジュール間の利便性だけを目的としたインポートを防ぐ。
- テストでは本番パッケージの構造を反映する。
- 生成コード、配布用素材、文書生成ツール、テスト用ユーティリティは、それぞれ指定されたモジュールに置く。
機能が境界をまたぐ場合は、アーキテクチャを迂回せず、各担当層を明示的に変更する。
## エラーの種類を分け、共有の状態をロックで守る
APIの境界で、プロジェクト標準の事前条件ヘルパーと対処方法が分かるメッセージを使って入力を検証する。呼び出し元が利用者の誤り、再試行可能な失敗、未検査の内部障害を区別できるよう、例外階層を保つ。
- 確立されたFutureユーティリティとエラーハンドラーを通じて、非同期処理の失敗を伝播させる。
- 文書化された理由なしに処理をブロックせず、非同期処理を合成する。
- 明示的なロックで共有された可変状態を保護し、保護対象のフィールドを記載する。
- ロック外からのアクセスが必要な場合に限り、可視性を保証する仕組みを使う。
- 構造化されたリソース管理によってリソースを閉じる。
- クリーンアップが繰り返される可能性がある場合は、close操作を冪等にする。
チェック対象の失敗を隠したり、再試行可能なエラーと恒久的なエラーを区別のない1つの例外へまとめたりしない。
## 設定のキーと通信メッセージの形式の互換性を保つ
必要に応じて、既定値、説明、任意の値、非推奨キーの取り扱いを備えた型付きビルダーで設定を定義する。階層的で一貫したキーを使い、リポジトリの設定抽象化を通じて値へアクセスする。
シリアル化とリモートメッセージでは、次を守る。
- 宣言されたスキーマとプロトコルのバージョンを維持する。
- そのバージョンでサポートされるフィールド形式だけを使う。
- スキーマの変更後は、標準ジェネレーターでコードを再生成する。
- 通信路上のメッセージを不変に保ち、内部転送型にはその旨を示す。
- 任意フィールドを明示的に表現する。
- 生成ワークフローが管理しているファイルを直接編集しない。
設定または通信契約が変わるたびに、互換性テストと生成文書を更新する。
## プロジェクトのテストツールで、単体テストと結合テストを書く
リポジトリが採用するテストフレームワーク、アサーションライブラリ、命名規則、拡張機能、基本フィクスチャを使う。全体のテストハーネスと競合する別のアサーションやタイムアウト機構を混在させない。
- 局所的な動作には焦点を絞った単体テストを、コンポーネント間の契約には統合テストを書く。
- テスト対象の動作が分かる、説明的なテスト名を使う。
- 成功結果と想定される失敗の両方をアサートする。
- 並行するインフラを新設せず、サポート済みのクラスター、ストレージ、サービスのフィクスチャを再利用する。
- まず影響範囲の狭いテストを実行し、次に直接影響するテスト群を実行する。
- 修正の証明として使う前に、意図した理由でそのテストが失敗することを確認する。
内部実装の詳細が契約の一部でない場合は、公開された動作を通じてテストする。
## ビルドとチェックを、プロジェクトのビルドラッパーで行う
ビルド、書式設定、静的解析、ライセンスチェック、コード生成、テストにはリポジトリのラッパーを使う。標準コマンドは、ツールを直接呼び出すと見落とす生成素材の準備や互換性の強制を行う場合がある。
- 宣言されたソースターゲットを保ちながら、文書化されたツールチェーンでビルドする。
- ローカルサービスの依存要素とコンポーネントを文書化された順序で起動する。
- サポートされる設定ファイルと値だけを編集する。
- 静的チェックの前に書式設定を実行する。
- 広範な検証の前に、影響を受けるテスト群を実行する。
- 変更がテスト対象の動作に影響し得る場合は、カバレッジプロファイルを使う。
完了を報告する前に継続的インテグレーションの各段階を理解し、該当する段階を手元で再現する。
## フォーマッターに従い、差分に関係ない変更を混ぜない
強制されるインポート順、修飾子順、配列構文、波括弧の規則、空白ポリシー、命名規則に従う。機械的な書式は標準フォーマッターに解決させる。
- ワイルドカードインポートと、リポジトリで禁止されるコメントマーカーや帰属タグを避ける。
- プロジェクトで要求される場合は、公開APIとprotected APIを文書化する。
- 可読性を損なうほどコードを詰め込むのではなく、まとまりのある責務を抽出してファイルサイズの上限を守る。
- コマンド、設定、互換性、公開動作が変わったら文書を更新する。
- 最終差分を確認し、無関係な書き換え、生成ファイルの意図しない編集、機密情報、未完了の後片付けがないか調べる。
焦点を絞った動作変更と無関係なリファクタリングを組み合わせない。
## 変更はレビュー用のブランチで出し、force-pushしない
許可されたブランチで作業し、pushする前にすべてのリモートを確認する。上流または共有ブランチを保護し、保護対象へ直接書き込まず、プロジェクトのレビュー経路を通じて変更を提出する。
- 文書化されたワークフローに従い、標準のベースブランチを基準にrebaseまたは更新する。
- コンポーネントに範囲を絞った簡潔なコミット件名を書き、必要な場合は本文で動機を説明する。
- 提出前にブランチの差分全体を確認する。
- 書式設定、静的チェック、ライセンスチェック、影響を受けるテストを実行する。
- レビュー依頼に平易な要約とテスト計画を含める。
- 貢献ポリシーで求められる場合は、支援を受けた変更を人間によるレビューの対象として示す。
明示的な許可なしに共有ブランチへforce-pushしたり、履歴を破壊する操作を使ったりしない。
## 新しい依存関係やリセットなど、大きな作業や壊す操作の前に聞く
既存の規則に従う、範囲を限定した読み取り、ローカルビルド、テスト、書式設定、診断、修正は自律的に進める。モジュールをまたぐリファクタリング、新しい依存関係、スキーマ移行、ビルドシステムの変更、継続的インテグレーションの変更、破壊的操作など、広範または重大な作業の前には確認を求める。
明示的な許可がなければ、次の操作は決して行わない。
- 認証情報や機密値をコミットする。
- 保護された上流の対象へ直接pushする。
- 共有履歴へforce-pushしたり、ブランチを消去したりする。
- hard resetや破壊的なクリーンアップを実行する。
- hook、静的チェック、書式規則を迂回する。
- 元のソースではなく、生成済み成果物を変更する。
- 合格結果を得るために品質ゲートを弱める。
完了前に、テスト、書式設定、静的チェック、必須ヘッダー、意図した差分全体を確認する。範囲や可逆性が不明な場合は停止し、必要な判断を説明する。
