DDDにおけるサービスとは
DDDでは、エンティティ、値オブジェクト、集約といった「ドメインオブジェクト」だけではなく、それらの外に記述したほうがよいロジックも存在します。そのようなときに、状態を持たないステートレスな「サービス」を使用できます。サービスには、大きく分けて次の2つが存在します。
- ドメインサービス:エンティティや値オブジェクトの責務ではないドメインモデルのロジック(複数のドメインオブジェクトを使って計算する処理やファサード)
- アプリケーションサービス(詳細は14章):非常に薄く、ドメインモデル上のタスクの調整に使うロジック(腐敗防止層の変換・アダプター等)
ドメインサービスの特徴
ドメインサービスの特徴は、ドメイン層の中に含まれ、ビジネスロジックを持つことができる点にあります。本章では、このドメインサービスを中心にご紹介します。
アプリケーションサービスの特徴
ドメインサービスに対して、アプリケーションサービスはドメイン層を使うアプリケーション層に含まれ、トランザクションやセキュリティのような調整的な処理を行います。
アプリケーションサービスを活用する例として、コンテキストの統合時に使われる「変換サービス」も存在します。他のコンテキストと連携し、腐敗防止層(3章)を実装する際に、専用のアダプターと変換サービスを用い、ドメインモデルの変換を行う場合があります。この詳細は、境界づけられたコンテキストの統合(13章)にて紹介します。
DDDの「ドメインサービス」と一般的な「サービス」の違い
一般的な「サービス」という言葉には、複雑なビジネスロジックを使いやすい粒度にまとめたコンポーネントというイメージがあります。また、4章のサービス指向アーキテクチャー(SOA)やRESTで紹介した、リモートプロシージャ呼び出し(RPC)やメッセージ指向ミドルウェア(MoM)を使って、分散システム間で協調する処理を担うことを指す場合もあります。
しかし、DDDの「ドメインサービス」は従来の「サービス」が示すものとは異なります。「ドメインサービス」は粒度が粗いコンポーネントではなく、トランザクションの責務を担うわけでもありません。
ドメインサービスの役割は、ドメインモデルが扱う「粒度の細かい処理」を担うものです。その処理がエンティティ(5章)/値オブジェクト(6章)/集約(10章)でもない場合に、ドメインサービスとして実装します。そのため、ドメインサービスはユビキタス言語として表現されます。
ドメインサービスで実装する内容
ドメインサービスで実装する主な内容としては「さまざまなエンティティ/値オブジェクト/集約を利用して計算するビジネスルール」が挙げられます。また、クライアント側が複雑にならないように、ドメインオブジェクトの構成を変換したり、ビジネスロジックをまとめたりする際にもドメインサービスは使用されます。
DDD本におけるドメインサービスの解説
IDDD本では、ドメインサービスの説明として、エヴァンス氏の次の説明を引用しています。
ときには、単純に「物」とはできないこともある。……ドメインにおける重要なプロセスや変換処理が、エンティティや値オブジェクトの自然な責務ではない場合、その操作は、サービスとして宣言される独立したインターフェイスとしてモデルに追加すること。モデルの言語を用いてインターフェイスを定義し、操作名が必ずユビキタス言語の一部になるようにすること。サービスには状態を持たせないこと。
このように、エヴァンス氏はドメインオブジェクトの責務に適さない重要な操作をドメインサービスとして実装する方向性を示しています。