新たな言葉も積極的にと思い勉強
※現場にてDDD駆動開発を行ったことはないため、誤情報があれば、ご了承ください。
DDD駆動開発とは
概要
DDD駆動開発(Domain-Driven Design)は、
業務(ドメイン)のルールや概念を中心にシステムを設計・実装する開発手法である。
技術構成ではなく、業務の考え方をコードの中心に据えることを目的とする。
従来の開発との違い
従来の開発
・業務ロジックがServiceクラスに集中しやすい
・if文や条件分岐が増え、可読性が低下する
・仕様変更時の影響範囲が広くなる
DDD駆動開発
・業務ロジックをドメインオブジェクトに集約
・Serviceは処理の流れを制御する役割に限定
・業務変更に強い構造になる
DDD駆動開発の考え方
業務ロジックの配置
業務上の判断やルールは、
Serviceではなく「業務を表すオブジェクト」が持つ。
例:
order.confirm()
→ 「注文を確定する」という業務をそのまま表現している。
主な構成要素
エンティティ(Entity)
・一意な識別子を持つ
・状態と業務ロジックを保持する
例:
注文、会員、契約 など
値オブジェクト(Value Object)
・識別子を持たない
・不変(Immutable)
・値そのものに意味を持たせる
例:
金額、メールアドレス、日付範囲
集約(Aggregate)
・データ整合性を保つ単位
・外部から直接操作できるのは集約ルートのみ
リポジトリ(Repository)
・エンティティの永続化を担当
・DB操作の詳細を隠蔽する
アーキテクチャ例
Controller
↓
Application Service
↓
Domain(Entity / Value Object)
↓
Repository
DDD駆動開発のメリット
・業務内容がコードから理解しやすい
・変更に強く、保守性が高い
・業務とシステムの認識ズレを減らせる
注意点
・初期設計コストが高い
・小規模、短期開発では過剰になる場合がある
・チーム全体での理解が必要
実務での位置づけ
実務では、
DDDの概念をすべて厳密に適用するのではなく、
エンティティに業務ロジックを持たせるなど、
部分的に取り入れるケースが一般的である。
DDDじゃない例(よくあるService肥大)
public class OrderService {
public void confirmOrder(OrderDto dto) {
if (dto.getPrice() <= 0) {
throw new IllegalArgumentException("金額不正");
}
if ("CANCEL".equals(dto.getStatus())) {
throw new IllegalStateException("キャンセル済み");
}
dto.setStatus("CONFIRMED");
}
}
問題点
・業務ルールがServiceに集中
・Orderはただの箱
・if文が増殖する
DDD駆動開発の例(役割分担が明確)
エンティティ(業務の主役)
public class Order {
private OrderId id;
private OrderStatus status;
private Money price;
public Order(OrderId id, Money price) {
this.id = id;
this.price = price;
this.status = OrderStatus.NEW;
}
public void confirm() {
if (status == OrderStatus.CANCEL) {
throw new IllegalStateException("キャンセル済みの注文は確定できません");
}
this.status = OrderStatus.CONFIRMED;
}
}
Service(流れだけ制御)
public class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
public void confirmOrder(OrderId id) {
Order order = orderRepository.findById(id);
order.confirm();
orderRepository.save(order);
}
}
Serviceは
・if文ほぼなし
・業務判断なし
・呼ぶだけ
まとめ
DDD駆動開発とは、
業務ルールをServiceに集約せず、
業務オブジェクトに責務として持たせる設計・開発手法である。