第54章:AIに「DDDのパーツ」を生成させるための指示テンプレート 🤖🧩✨

(AI時代に1人で開発するからこそ必要な、迷わないための100章🧭)
0. この章でできるようになること 🎯
- AIに「値オブジェクト」「エンティティ」「集約」「リポジトリ」などをブレずに作らせるための“型”を持てる
- ありがちな事故(AIが勝手にルール増やす/層を破る/責務が混ざる)を防げる
- コピペで使えるテンプレを手に入れる ✨
1. なんでテンプレが必要なの?🥺💦
AIって便利だけど、放っておくとこうなりがち👇
- ルールが曖昧 → AIがそれっぽく補完して別物を作る😇
- 層の境界が曖昧 → DomainにEF CoreやDTOが混ざる🌀
- 何を出力すべきか曖昧 → コードだけ出してテスト無し、使い方無し😢
なので、AIには最初からこう言ってあげるのが大事👇
「この役割で」「この言葉で」「この制約で」「この形式で」出してね😊
2. AIに渡すべき“最低セット”📦✨
DDDパーツ生成で、AIに渡す情報はいつもこの4つが核です💡
- ユビキタス言語(単語帳)📚
- 不変条件(守るべきルール)🔒
- 境界(やっていいこと/ダメなこと)🚧
- 出力形式(何を出すか)🧾
これが揃うと、AIの出力が急に安定します👍✨
3. 万能「ベーステンプレ」🧠📌(まずこれをコピペ)
下のテンプレを、AIチャット(Copilot ChatでもOK)に貼って、{ }を埋めて使ってね😊
あなたはDDDに詳しいC#設計アシスタントです。
以下のルールに従って、DDDのパーツを生成してください。
【目的】
{このパーツで実現したいことを1〜2行}
【ドメイン文脈(超重要)】
- アプリ概要:{何のアプリ?}
- 対象ユーザー:{誰が使う?}
- 主要ユースケース:{例:会員登録、注文、予約 など}
【ユビキタス言語(単語帳)】
- {用語A}:{意味}
- {用語B}:{意味}
- {用語C}:{意味}
【不変条件(絶対守るルール)】
- ルール1:{例:Emailは形式が正しい}
- ルール2:{例:Moneyは負数不可}
- ルール3:{例:注文は確定後に明細変更不可}
【境界・制約(やらないこと)】
- Domain層にDB/ORM/HTTP/DTO/Controllerの概念を入れない
- 例外乱発しない(必要ならResultパターンで返す)
- public set を安易に作らない(不変性を優先)
- 生成するのは「最小で正しい」構成(やりすぎ禁止)
【技術ルール】
- C#で実装
- null安全を意識(nullable前提)
- 可能なら immutable を優先
- 名前はユビキタス言語に合わせる
【出力してほしいもの】
1) 実装コード(必要な型すべて)
2) 使い方の短い例(数行)
3) 最低限のユニットテスト(xUnit想定でOK)
4) 設計意図(箇条書きで短く)
【今回生成してほしいDDDパーツ】
{Value Object / Entity / Aggregate / Repository / Domain Event / Domain Service など}
+ 追加指示:{あれば}
4. パーツ別テンプレ(コピペ用)🧩✨
4-1) 値オブジェクト(Value Object)テンプレ 💎
「string を信じない」ための最強パーツだよ😊
「値オブジェクト」を1つ生成してください。
【対象】
名前:{例:EmailAddress}
表現したい意味:{例:ユーザーのメールアドレス}
内部表現:{例:string}
【不変条件】
- {例:空文字不可}
- {例:メール形式のみ許可}
- {例:前後空白はトリムして保持}
【欲しい仕様】
- 作成は static Create(...) で行い、成功/失敗をResultで返す
- Equalsは値で比較(record/record struct歓迎)
- ToString() は {例:メール文字列} を返す
- 可能なら正規化(例:小文字化)
【出力形式】
- 実装コード + 使用例 + テスト + 意図
✅AIがよくやるミス:
- コンストラクタpublicで誰でも不正値を作れる😇 → Createに寄せる
- Validationが外に漏れる → VO内部で完結させる
4-2) エンティティ(Entity)テンプレ 🧍♀️🧍♂️
「同一性(ID)」を持つやつ!
「エンティティ」を生成してください。
【対象】
名前:{例:User}
識別子:{例:UserId(専用型)}
主要プロパティ:{例:EmailAddress, DisplayName}
状態変更:{例:表示名変更、メール変更}
【不変条件】
- {例:DisplayNameは1〜20文字}
- {例:Email変更時は形式チェック必須}
【制約】
- IDは不変(後から変えない)
- public set を作らず、メソッド経由で変更させる
- 例外ではなくResultで失敗を返す
【出力形式】
- 実装コード + 使用例 + テスト + 意図
4-3) 集約(Aggregate)テンプレ 🏰✨
「関連オブジェクトを1つのチームとして守る」やつ!
「集約ルート」を生成してください。
【対象】
集約名:{例:Circle}
集約ルート:{例:Circle}
子要素:{例:Member(エンティティ or VO)}
外から触っていい入口:ルートのメソッドだけ
【守るルール(超重要)】
- {例:メンバーは最大30人}
- {例:同じEmailのメンバーは追加できない}
- {例:退会した人は再追加できない}
【欲しい操作】
- AddMember(...)
- RemoveMember(...)
- ChangeName(...)
【ドメインイベント(任意)】
- {例:MemberAdded}
- {例:MemberRemoved}
※イベントは「起きた事実」だけ。副作用は別で処理。
【制約】
- 子要素の追加/削除はルート経由のみ
- コレクションは外に生で返さない(読み取り専用にする)
- 例外ではなくResultで返す
【出力形式】
- 実装コード(イベント含む)+ 使用例 + テスト + 意図
4-4) リポジトリ(Repository)テンプレ 📦🗃️
「保存・復元」を隠す箱!
「リポジトリ」を生成してください。
【対象】
集約:{例:Circle}
ID:{例:CircleId}
【必要メソッド】
- Task<Circle?> FindByIdAsync(CircleId id, CancellationToken ct)
- Task SaveAsync(Circle aggregate, CancellationToken ct)
- Task<bool> ExistsAsync(CircleId id, CancellationToken ct)(必要なら)
【制約(絶対)】
- Domain層にはRepositoryの「インターフェース」だけ
- DBやORMのコードはInfrastructure側(例:EF Core)に置く前提
- 例外ポリシー:DB例外は上位へ投げる/Resultで包む、どちらか選び理由も書く
【出力形式】
- Domain: ICircleRepository(インターフェース)
- Infrastructure: 仮の実装スケルトン(DBは擬似でもOK)
- 使用例 + 最低限テスト(モックでOK)+ 意図
4-5) Resultパターン(失敗を戻り値で)テンプレ ✅❌
「例外で制御しない」ための便利道具!
C#でResultパターンを実装してください。
【要件】
- Result(成功/失敗)
- Result<T>(成功時に値を持つ)
- 失敗理由はエラーコード+メッセージ(簡易でOK)
- 使いやすい補助メソッド:Success/Failure
【制約】
- 例外で業務エラーを表現しない(想定内の失敗はResult)
- nullを成功値にしない(必要ならOptional設計を提案)
【出力形式】
- 実装コード + 使い方例 + テスト + 意図
5. “AIに崩されない”ためのコツ7つ 🧷✨
-
「単語帳」を先に渡す📚(名前が揺れると全部崩れる)
-
不変条件を箇条書きで🔒(ここが設計の心臓)
-
やらないことを書く🚫(DomainにDB入れない等)
-
出力形式を指定する🧾(コードだけ出される事故防止)
-
“最小で正しい”を明記🪶(AIは盛りがち😂)
-
1パーツずつ依頼する🧩(まとめ依頼は混線しやすい)
-
最後にセルフレビューさせる🕵️♀️
- 「DDDの層を破ってない?」
- 「public set入れてない?」
- 「不変条件はコードで守れてる?」
セルフレビュー用の追いプロンプトも置いとくね👇😊
今出したコードを自己レビューしてください。
- DDDの層を破っていないか(DomainにDB/DTO/ORMが混ざってないか)
- 不変条件がコードで保証されているか
- public set や不必要な可変がないか
- 命名がユビキタス言語と一致しているか
問題があれば、修正案と修正版コードを提示してください。
6. ミニ実演:テンプレで「EmailAddress」を作らせる ✉️✨
AIに投げる文(例)👇
「値オブジェクト」を1つ生成してください。
【対象】
名前:EmailAddress
表現したい意味:ユーザーのメールアドレス
内部表現:string
【不変条件】
- null/空文字不可
- メール形式のみ許可
- 前後空白はトリムして保持
- 小文字に正規化して保持
【欲しい仕様】
- static Create(string raw) で作る。成功/失敗は Result<EmailAddress>。
- record(またはrecord struct)で値比較
- ToString() はメール文字列
【出力形式】
実装コード + 使用例 + xUnitテスト + 設計意図
この形で投げると、かなり高確率で“使えるVO”が返ってきます😊👍
7. 演習(今日の分)✍️🌟
あなたの作りたいアプリを題材にしてOKだよ〜!
演習A:単語帳づくり📚
次を3〜8個書いて、AIに渡してみてね✨
- 用語:意味 例)「申込」:イベントに参加する意思を登録すること
演習B:テンプレで1パーツ生成🧩
上の「値オブジェクト」テンプレで、どれか1つ作ってみよう😊
- EmailAddress / Money / UserId / ProductCode など
演習C:自己レビュー🕵️♀️
生成後、セルフレビュー用プロンプトを投げて修正させてみよう!
8. まとめ 🎀
- AIは“賢い”けど、“文脈と制約”がないと平気で迷子になります🥺
- テンプレは、未来の自分のための「設計の手すり」🧸✨
- 単語帳 + 不変条件 + 境界 + 出力形式、この4点セットが最強💪😆
次の第55章は、いよいよ手を動かして「お金(Money)」「メール(Email)」を値オブジェクトで作る演習だよ〜💰✉️✨