arch-fitness-functions について
自動チェックでアーキテクチャ上の決定を維持したいチーム向けのスキルです。CIや本番環境で実行するフィットネス関数を説明し、依存関係、レイヤー境界、性能特性の検査を扱います。
主な機能
- 01アーキテクチャルールの自動検査
- 02CIで違反時にビルドを失敗させる
- 03静的・動的チェック
- 04依存方向とレイヤー境界の検証
- 05本番環境の性能特性の監視
活用シーン
- 01アーキテクチャ決定の継続的な適用
- 02モジュールの依存方向の逸脱防止
- 03移行プロジェクトの新規コードの制約
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill arch-fitness-functionsインストール後、Claude Code で/arch-fitness-functionsを入力して読み込まれたか確認します。
詳細
1行での概要
アーキテクチャ上の意図を、変更のたびに実行される自動チェックとして定義します。アーキテクチャで「ドメイン層は Spring に依存しない」と定めている場合、依存してしまうとフィットネス関数がビルドを失敗させます。
このスキルを使う場面
- アーキテクチャ上の重要な判断があり、それを長期にわたって維持する必要がある場合(依存関係の方向、レイヤーの境界、循環依存の禁止、パフォーマンス予算など)。
- チームが大きく、非公式な「X はしないと合意した」という約束をすべての PR で守れない場合。
- 移行プロジェクト(
arch-strangler-fig)で、新しいコードをレガシーではなく新しい構造に配置することを徹底したい場合。 - アーキテクチャ上の判断について、逸脱の検出をコードレビューに頼ることになる場合。
このスキルを使わない場面
- プロジェクトが小規模で、開発者が1人であり、拡張性の問題がない場合。
- アーキテクチャ上の特性が本質的に主観的で、自動化できない場合(好み、美的感覚、特殊なケースでの命名スタイルなど)。
- 過剰な取り締まりになる場合。アーキテクチャ上のルールにはすべてコストがあります。PR を却下するほどのものだけを適用してください。
主な内容
フィットネス関数とは、アーキテクチャ上の特性を検証するテストです。ユニットテストと同様に、次の特徴があります。
- 変更のたびに CI で自動的に実行されます。
- 違反があればビルドを失敗させます。
- 実行可能な形式で、アーキテクチャ上の意図を記録します。
フィットネス関数のカテゴリ(Ford、Parsons、Kua、Building Evolutionary Architectures):
- アトミックとホリスティック。 アトミックなチェックは単一の特性を検証します(このモジュールに循環依存がないこと)。ホリスティックなチェックは複数の特性を組み合わせます(負荷時のパフォーマンスと正確性)。
- トリガー実行と継続実行。 トリガー実行はビルドのたびに実行されます(最も有用です)。継続実行は本番環境で実行されます(レイテンシの予算、エラー率など)。
- 静的と動的。 静的チェックはコードを解析します(依存関係の方向など)。動的チェックはシステムを実行します(応答時間のチェックなど)。
一般的な静的フィットネス関数(最初に取り組むのに最も手軽なものです):
- 依存関係の方向。 「モジュール X はモジュール Y に依存してはならない」。ビルドグラフまたは専用ライブラリ(JVM の ArchUnit、TypeScript の ts-arch、JS の dependency-cruiser)で適用します。
- 循環依存の禁止。 誤った場所に配置された import によって生じた意図しない循環依存を検出します。
- 命名規則。 「
controller/内のすべてのクラス名はControllerで終わること」。主に見た目の問題ですが、簡単に適用できます。 - パブリック API の安定性。 「このインターフェースに新しいパブリックメソッドを追加する場合は、対応するテストも必要」。カスタムチェックで対応します。
- レイヤー境界への違反。 「
domain/内のコードはinfrastructure/からインポートしてはならない」。典型的なヘキサゴナルアーキテクチャのチェックです。
本番環境のアーキテクチャ向けの動的フィットネス関数:
- p99 レイテンシがしきい値を下回ること。
- メモリ使用量に上限があること。
- 特定のビジネス不変条件が保たれていること(残高が負にならないこと、注文が重複しないこと)。
ArchUnit を使った例(JVM で、最も成熟したエコシステムです):
@ArchTest
val domainHasNoSpringDependencies =
noClasses().that().resideInAPackage("..domain..")
.should().dependOnClassesThat().resideInAPackage("org.springframework..")
判断のヒューリスティクス
- まず、アーキテクチャの最も重要な特性(通常は依存関係の方向)を適用するフィットネス関数を1つか2つ導入します。逸脱が見られるようになったら追加します。
- フィットネス関数の失敗によってビルドが失敗するようにします。1年間無視されている警告は、フィットネス関数とは言えません。
- フィットネス関数はテストと同様に扱います。それぞれの失敗メッセージで、ルールが何をチェックするのかだけでなく、なぜそのルールがあるのかも明確に説明してください。
- PR を却下するほどではないルールに、フィットネス関数を書かないでください。
- 移行プロジェクトでは、「新しいコードはレガシーのパス Y ではなく、パス X に配置する」というルールをフィットネス関数に定義できます。移行の健全性を保つうえで非常に役立ちます。
アンチパターン
- 誰も所有者にならないフィットネス関数。 破損する → 誰かが無効にする → そのまま永久に回避されます。
- 過剰な取り締まり。 あらゆる好みを強制するフィットネス関数が何百もあります。CI が遅くなり、開発者は失敗を無視するようになります。
- スタイルをアーキテクチャとして扱う。 「すべてのメソッド名を camelCase にする」はリンタールールであり、フィットネス関数ではありません。この用語を安易に使わないでください。
- 自動化を伴わないドキュメント。 アーキテクチャを説明する Wiki ページがあっても、自動チェックがなければ、新しく参加したメンバーは数週間以内にそのルールに違反します。
- 一度きりのチェック。 アーキテクチャ監査を一度だけ行い、結果を保管します。その直後から、すぐに乖離が蓄積します。
関連項目
arch-layered— レイヤー境界は、フィットネス関数の典型的なユースケースです。arch-hexagonal— ドメインに向かう依存方向は、ヘキサゴナルアーキテクチャにおける典型的なフィットネス関数です。arch-adr— フィットネス関数は 何を 行うかを定め、ADR は なぜ それを行うかを説明します。両者はセットで扱う必要があります。
参考資料
- Neal Ford、Rebecca Parsons、Patrick Kua、『Building Evolutionary Architectures』(O'Reilly、第2版)— 基礎となる参考資料です。
- ArchUnit のドキュメント(JVM)。
- Richards & Ford、『Fundamentals of Software Architecture』、ガバナンス/フィットネスに関する章。
コメント
Markdown 対応