
Entity / ValueObject / Repository / Aggregate を理解したうえで、「Service(サービス)」の役割を押さえると、DDD(ドメイン駆動設計)の全体像が一気にクリアになります。
そのServiceパターンそのモモについてと、の2種類の特色について紹介します。
Serviceとは何か?
Service(サービス) は「オブジェクトの振る舞いを外に出したもの」です。
Entity や ValueObject に属さないロジックを扱うための補助的な役割パターンです。
2種類のServiceパターン
| 種類 |
主な責務 |
どこに属するか |
例 |
| Domain Service(ドメインサービス) |
ビジネスロジックの中核 |
ドメイン層 |
購入金額の割引計算、在庫引当、決済処理など |
| Application Service(アプリケーションサービス) |
ユースケースの調整・外部入出力 |
アプリケーション層 |
コントローラからドメインを呼び出し、結果を返す |
① Domain Service(ドメインサービス)
ドメインサービスには次のような特徴があります。
・複数のエンティティや値オブジェクトに関わるビジネスルールをまとめる場所。
・ビジネス上の「動作」を表すが、状態(プロパティ)は持たない。
・エンティティの責務にすべきでない、横断的なロジックを担当。
サンプルコード
注文と在庫をまとめて扱うサービス
class StockService {
constructor(stockRepository) {
this.stockRepository = stockRepository;
}
canPurchase(productId, quantity) {
const stock = this.stockRepository.findByProductId(productId);
return stock && stock.amount >= quantity;
}
decreaseStock(productId, quantity) {
const stock = this.stockRepository.findByProductId(productId);
stock.amount -= quantity;
this.stockRepository.save(stock);
}
}
ポイント解説
StockService は「ビジネスロジック」を扱うクラス。
ただし、UIやDB接続には関知しない。
エンティティに属さない「在庫引当」「料金計算」などをまとめる役割。
② Application Service(アプリケーションサービス)
アプリケーションサービスには、次のような特徴があります。
・ユースケース(アプリ全体の操作の流れ)を制御する層。
・コントローラやAPIなどの外部インターフェースと、ドメイン層(Entity / Repository / DomainService)をつなぐ。
・ビジネスロジック自体は持たない。
サンプルコード
注文処理のアプリケーションサービス
class OrderApplicationService {
constructor(orderRepository, stockService) {
this.orderRepository = orderRepository;
this.stockService = stockService;
}
placeOrder(customerId, productId, quantity) {
// 1. 在庫確認(ドメインサービスを利用)
if (!this.stockService.canPurchase(productId, quantity)) {
throw new Error("在庫不足です");
}
// 2. 注文作成(エンティティ)
const order = new Order(Date.now(), customerId);
order.addItem(productId, quantity);
// 3. 在庫減少(ドメインサービス)
this.stockService.decreaseStock(productId, quantity);
// 4. 永続化(リポジトリ)
this.orderRepository.save(order);
return order;
}
}
ポイント解説
アプリの流れ(ユースケース)を記述する場所。
ビジネスルール(割引計算など)はDomainServiceに委譲。
コントローラなどから直接呼び出される。
関係性まとめ(全体図)
[ Controller / API ] ← ユーザー操作
│
▼
[ Application Service ] ← ユースケース制御
│
▼
[ Domain Service ] ← ビジネスルール(ドメイン知識)
│
▼
[ Entity / Value Object / Repository ] ← データモデル
違いのまとめ
| 観点 |
Domain Service |
Application Service |
| 目的 |
ビジネスルールの表現 |
ユースケースの流れ制御 |
| 属する層 |
ドメイン層 |
アプリケーション層 |
| 状態 |
持たない |
持たない |
| 呼び出し元 |
Application Service |
Controller / API |
| 依存先 |
Entity, ValueObject, Repository |
DomainService, Repository |
| 例 |
割引計算、在庫確認、決済処理 |
注文受付、ユーザー登録、メール送信 |
あとがき
普通にClassを作成して、constructorでnewインスタンス起動する処理を設けた場合の基本記述っぽいですが、
Domainサービスも、Applicationサービスも、実際の処理を持たないという点で、受け渡しをするクラスという意味合いが強いようです。
MVCのコントローラに改装を持たせるなら、上位に設置するクラスのようなイメージが持てますね。
色々なデザインパターンと組み合わせて使える基本的なサービスと言うパターンが理解できました。
0 件のコメント:
コメントを投稿