DDDってなんなの?
DDD(ドメイン駆動設計)入門
初めまして!学生エンジニアの kazu です。
今回は、インターン先でよく見かけた DDD(Domain-Driven Design / ドメイン駆動設計) について整理してみます。
最初は「何それ…?」と思いましたが、実務やAIとの壁打ちで少しずつ理解できてきました。
この記事では、躓きやすいポイントや自分の学びを交えつつ、DDDの本質を解説します。
そもそもDDDって何?
DDD(Domain Driven Design) とは、
「ビジネス(ドメイン)の意味を中心にコードを設計する考え方」です。
- 技術やアーキテクチャではなく、業務ルールを正しく表現することが目的
- 「クリーンアーキテクチャの層構造」などはDDDの本質ではなく、あくまで 実装手段 にすぎません
Value Object(値オブジェクト)
Value Object は、一意なIDを持たず、値で同一性を判断するオブジェクトです。
ビジネスルールを型に閉じ込めるために使います。
例:Email
type Email struct {
value string
}
func NewEmail(v string) (Email, error) {
// 簡易的なメールアドレス形式チェック
re := regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
if !re.MatchString(v) {
return Email{}, errors.New("メールアドレスの形式が不正です")
}
return Email{value: v}, nil
}
func (e Email) String() string {
return e.value
}
ポイント:
値にドメイン制約(ここではメール形式)を付ける
同じ値なら同一とみなす
制約がない場合はプリミティブ型(string等)で十分
Entity(エンティティ)
-
Entity は 一意なIDを持ち、状態を持つオブジェクト です。
-
同じ属性でもIDが違えば別のEntity
-
Value Object をフィールドに持つことも多い
-
複数属性にまたがるドメインルールを表現できる
例:User
type User struct {
id uuid.UUID
name string
email Email
createdAt time.Time
updatedAt time.Time
}
// コンストラクタ
func NewUser(name string, email Email) (User, error) {
now := time.Now()
user := User{
id: uuid.New(),
name: name,
email: email,
createdAt: now,
updatedAt: now,
}
if err := user.Validate(); err != nil {
return User{}, err
}
return user, nil
}
// 複数フィールドにまたがるバリデーション
func (u User) Validate() error {
if u.createdAt.After(u.updatedAt) {
return errors.New("作成日時が更新日時より後です")
}
return nil
}
ポイント:
Value Object は単一値の制約を担当
Entity は IDと状態、複数属性間の制約を担当
Domain Service(ドメインサービス)
Domain Service は、Entity や Value Object 単体では表現しきれないドメインルール を定める場所です。
特に、複数の Entity や Value Object が絡む場合に使います。
例:ユーザー名の一意性チェック
-
単一の User Entity 内ではチェックできない
-
他の User Entity を参照する必要があるため、Domain Service で実装
type UserService struct {
repo UserRepository
}
func (s UserService) IsNameUnique(name string) (bool, error) {
exists, err := s.repo.ExistsByName(name)
if err != nil {
return false, err
}
return !exists, nil
}
ポイント:
複数オブジェクトにまたがるビジネスルールを担当
リポジトリにアクセスすることが多いが、永続化はサービスの責務ではなく、あくまで補助
まとめ
-
DDDの本質 = ドメイン(ビジネス)を正しくモデル化すること
-
Value Object = 値の制約と意味を表す
-
Entity = 一意なIDと状態を持つオブジェクト
-
Domain Service = 複数オブジェクトにまたがるビジネスルール
-
層構造やリポジトリ = DDDを支える手段であり、本質ではない
終わりに
この記事には私の思想も含まれています。間違っていたら教えて頂けると助かります🙇
Discussion