clean-ddd-hexagonal
API・マイクロサービス・スケーラブルなバックエンド設計時に積極的に適用されるスキルで、DDD・クリーンアーキテクチャ・ヘキサゴナルアーキテクチャ・ポートとアダプター・エンティティ・値オブジェクト・ドメインイベント・CQRS・イベントソーシング・リポジトリパターン・ユースケース・オニオンアーキテクチャ・アウトボックスパターン・集約ルート・腐敗防止層などのキーワードで起動します。ドメインモデル・集約・リポジトリ・境界付けられたコンテキストを扱う際に活用でき、Go・Rust・Python・TypeScript・Java・C# など言語を問わずバックエンドサービスへのクリーンアーキテクチャ+DDD+ヘキサゴナルパターンの適用を支援します。
description の原文を見る
Proactively apply when designing APIs, microservices, or scalable backend structure. Triggers on DDD, Clean Architecture, Hexagonal, ports and adapters, entities, value objects, domain events, CQRS, event sourcing, repository pattern, use cases, onion architecture, outbox pattern, aggregate root, anti-corruption layer. Use when working with domain models, aggregates, repositories, or bounded contexts. Clean Architecture + DDD + Hexagonal patterns for backend services, language-agnostic (Go, Rust, Python, TypeScript, Java, C#).
SKILL.md 本文
クリーンアーキテクチャ + DDD + ヘキサゴナル
DDD の戦術的パターン、クリーンアーキテクチャの依存性ルール、ヘキサゴナルのポーツ/アダプタを組み合わせた、保守可能でテスト可能なバックエンドアーキテクチャ。
使用すべき場合(使用すべきでない場合)
| 使用すべき場合 | スキップすべき場合 |
|---|---|
| ビジネスルールが複雑で多い領域 | シンプルな CRUD で、ビジネスルールが少ない |
| 長期的に保守される(数年間) | プロトタイプ、MVP、使い捨てコード |
| 5 人以上の開発チーム | ソロ開発者または小規模チーム(1〜2 人) |
| 複数のエントリーポイント(API、CLI、イベント) | 単一のエントリーポイント、シンプルな API |
| インフラを交換する必要がある(DB、ブローカー) | インフラが固定、変更の可能性が低い |
| 高いテストカバレッジが必要 | クイックスクリプト、内部ツール |
シンプルに始めましょう。必要な場合にのみ複雑さを進化させます。 ほとんどのシステムは完全な CQRS やイベントソーシングを必要としません。
重要:依存性ルール
依存性は内側を指すのみです。外層は内層に依存し、その逆はありません。
インフラストラクチャ → アプリケーション → ドメイン
(アダプタ) (ユースケース) (コア)
捕捉すべき違反:
- ドメインがデータベース/HTTP ライブラリをインポート
- コントローラが直接リポジトリを呼び出し(ユースケースをバイパス)
- エンティティがアプリケーションサービスに依存
設計検証: 「UI またはデータベースがなくても機能するアプリケーションを作成する」— Alistair Cockburn。インフラなしでテストからドメインロジックを実行できれば、境界は正しいです。
クイック判定木
「このコードはどこに行くか?」
どこに行くか?
├─ 純粋なビジネスロジック、I/O なし → domain/
├─ ドメインをオーケストレートして副作用がある → application/
├─ 外部システムと通信 → infrastructure/
├─ インタラクション方法を定義(インターフェース)→ port (domain or application)
└─ ポートを実装 → adapter (infrastructure)
「これはエンティティか値オブジェクトか?」
エンティティか値オブジェクトか?
├─ 持続する一意のアイデンティティがある → エンティティ
├─ その属性のみで定義される → 値オブジェクト
├─ 「これは同じものか?」 → エンティティ(アイデンティティ比較)
└─ 「同じ値を持っているか?」 → 値オブジェクト(構造的等価性)
「これは独自の集約であるべきか?」
集約の境界?
├─ トランザクションで一緒に矛盾している必要がある → 同じ集約
├─ 最終的に矛盾していてもよい → 別の集約
├─ ID でのみ参照される → 別の集約
└─ 集約に 10 個以上のエンティティ → 分割する
ルール: トランザクションごとに 1 つの集約。ドメインイベント経由のクロス集約一貫性(最終的な一貫性)。
ディレクトリ構造
src/
├── domain/ # コアビジネスロジック(外部依存ゼロ)
│ ├── {aggregate}/
│ │ ├── entity # 集約ルート + 子エンティティ
│ │ ├── value_objects # 不変値型
│ │ ├── events # ドメインイベント
│ │ ├── repository # リポジトリインターフェース(駆動ポート)
│ │ └── services # ドメインサービス(ステートレスロジック)
│ └── shared/
│ └── errors # ドメインエラー
├── application/ # ユースケース/アプリケーションサービス
│ ├── {use-case}/
│ │ ├── command # コマンド/クエリ DTO
│ │ ├── handler # ユースケース実装
│ │ └── port # ドライバーポートインターフェース
│ └── shared/
│ └── unit_of_work # トランザクション抽象化
├── infrastructure/ # アダプタ(外部関心事)
│ ├── persistence/ # データベースアダプタ
│ ├── messaging/ # メッセージブローカーアダプタ
│ ├── http/ # REST/GraphQL アダプタ(ドライバー)
│ └── config/
│ └── di # 依存性注入/コンポジションルート
└── main # ブートストラップ/エントリーポイント
DDD の構成要素
| パターン | 目的 | レイヤー | キールール |
|---|---|---|---|
| エンティティ | アイデンティティ + 振る舞い | ドメイン | ID による等価性 |
| 値オブジェクト | 不変データ | ドメイン | 値による等価性、setter なし |
| 集約 | 一貫性の境界 | ドメイン | ルートのみ外部から参照 |
| ドメインイベント | 変更の記録 | ドメイン | 過去形の命名(OrderPlaced) |
| リポジトリ | 永続化の抽象化 | ドメイン(ポート) | 集約ごと、テーブルごとでない |
| ドメインサービス | ステートレスロジック | ドメイン | ロジックがエンティティに適さない時 |
| アプリケーションサービス | オーケストレーション | アプリケーション | ドメイン + インフラを調整 |
アンチパターン(重要)
| アンチパターン | 問題 | 修正 |
|---|---|---|
| 貧血ドメインモデル | エンティティがデータバッグ、サービスにロジック | 振る舞いをエンティティに移動 |
| エンティティごとのリポジトリ | 集約の境界を破壊 | 集約ごとに 1 つのリポジトリ |
| インフラリーク | ドメインが DB/HTTP ライブラリをインポート | ドメインに外部依存ゼロ |
| ゴッド集約 | エンティティが多すぎる、トランザクション遅い | 小さな集約に分割 |
| ポートをスキップ | コントローラが直接リポジトリを呼び出し | アプリケーションレイヤー経由 |
| CRUD 思考 | データをモデル化、振る舞いではなく | ビジネス操作をモデル化 |
| 時期尚早な CQRS | 必要となる前に複雑さを追加 | シンプルな読み書きで始める、進化させる |
| クロス集約トランザクション | 1 つのトランザクションで複数の集約 | 一貫性のためにドメインイベントを使用 |
実装順序
- ドメインを発見する — イベントストーミング、ドメイン専門家との対話
- ドメインをモデル化する — エンティティ、値オブジェクト、集約(インフラなし)
- ポートを定義する — リポジトリインターフェース、外部サービスインターフェース
- ユースケースを実装する — ドメインを調整するアプリケーションサービス
- アダプタを最後に追加する — HTTP、データベース、メッセージング実装
DDD は協調的です。 ドメイン専門家とのモデリングセッションはコードパターンと同じくらい重要です。
参照ドキュメント
| ファイル | 目的 |
|---|---|
references/LAYERS.md | レイヤー仕様全体 |
references/DDD-STRATEGIC.md | 境界付けられたコンテキスト、コンテキストマッピング |
references/DDD-TACTICAL.md | エンティティ、値オブジェクト、集約(疑似コード) |
references/HEXAGONAL.md | ポーツ、アダプタ、命名 |
references/CQRS-EVENTS.md | コマンド/クエリ分離、イベント |
references/TESTING.md | ユニット、統合、アーキテクチャテスト |
references/CHEATSHEET.md | クイック判定ガイド |
ソース
主要ソース
- The Clean Architecture — Robert C. Martin(2012)
- Hexagonal Architecture — Alistair Cockburn(2005)
- Domain-Driven Design: The Blue Book — Eric Evans(2003)
- Implementing Domain-Driven Design — Vaughn Vernon(2013)
パターン参考
- CQRS — Martin Fowler
- Event Sourcing — Martin Fowler
- Repository Pattern — Martin Fowler(PoEAA)
- Unit of Work — Martin Fowler(PoEAA)
- Bounded Context — Martin Fowler
- Transactional Outbox — microservices.io
- Effective Aggregate Design — Vaughn Vernon
実装ガイド
- Microsoft: DDD + CQRS Microservices
- Domain Events — Udi Dahan
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- ccheney
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/ccheney/robust-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。