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

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

AIに「DDDのパーツ」を生成させるための指示テンプレート

(AI時代に1人で開発するからこそ必要な、迷わないための100章🧭)


0. この章でできるようになること 🎯

  • AIに「値オブジェクト」「エンティティ」「集約」「リポジトリ」などをブレずに作らせるための“型”を持てる
  • ありがちな事故(AIが勝手にルール増やす/層を破る/責務が混ざる)を防げる
  • コピペで使えるテンプレを手に入れる ✨

1. なんでテンプレが必要なの?🥺💦

AIって便利だけど、放っておくとこうなりがち👇

  • ルールが曖昧 → AIがそれっぽく補完して別物を作る😇
  • 層の境界が曖昧 → DomainにEF CoreやDTOが混ざる🌀
  • 何を出力すべきか曖昧 → コードだけ出してテスト無し、使い方無し😢

なので、AIには最初からこう言ってあげるのが大事👇

「この役割で」「この言葉で」「この制約で」「この形式で」出してね😊


2. AIに渡すべき“最低セット”📦✨

DDDパーツ生成で、AIに渡す情報はいつもこの4つが核です💡

  1. ユビキタス言語(単語帳)📚
  2. 不変条件(守るべきルール)🔒
  3. 境界(やっていいこと/ダメなこと)🚧
  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つ 🧷✨

  1. 「単語帳」を先に渡す📚(名前が揺れると全部崩れる)

  2. 不変条件を箇条書きで🔒(ここが設計の心臓)

  3. やらないことを書く🚫(DomainにDB入れない等)

  4. 出力形式を指定する🧾(コードだけ出される事故防止)

  5. “最小で正しい”を明記🪶(AIは盛りがち😂)

  6. 1パーツずつ依頼する🧩(まとめ依頼は混線しやすい)

  7. 最後にセルフレビューさせる🕵️‍♀️

    • 「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)」を値オブジェクトで作る演習だよ〜💰✉️✨