状況:
最初のプロジェクトで [〜#〜] ddd [〜#〜] を実装しています。戦略パターンを正しく実装する方法を明確にしたいと思います(私の場合、APIトークンがアクティブかどうかを確認します)。これはApiTokenインスタンスのビジネスルールですが、この戦略にはさまざまな実装が考えられるため、このロジックを外部実装に委任したいと思います。
実装:
ApiToken
クラス:
public abstract class ApiToken {
public abstract boolean isActive(TokenActiveStrategy strategy);
}
これはトークン戦略コントラクトです:
public interface TokenStrategy {
boolean isActive(final ApiToken token);
}
そして使い方:
TokenStrategy tokenStrategy = new DatabaseTokenStrategy();
if (!token.isActive(tokenStrategy)) {
throw new AuthenticationException(ExceptionCodeType.TOKEN_NOT_ACTIVE);
}
そして具体的なApiTokenクラス:
@Override
public boolean isActive(final TokenStrategy strategy) {
return strategy.isActive(this);
}
質問:
DDDの原則に関して、ドメインオブジェクトのドメインビジネスルールoutのチェックを委任しても問題ありませんか?
ドメインオブジェクトは、それ自体のコンテキスト外の情報を提供する責任はありません。 APIトークンがアクティブであるかどうかは、トークン自体が回答できるものではなく、APIプロバイダーへの質問です。APIプロバイダーが真実の源です。
現実世界のよい例えは、車が登録されているかどうかを教えてもらえますか?いいえ、グローブボックスにナンバープレートや登録用紙が入っていてもできません。地元のAuto/Roads当局だけがその質問に正直に答えることができます。
私にとって、実装しようとしている機能(ApiToken
がアクティブかどうかの確認)は、ドメインサービスに常駐させる必要があります。次に、ドメインサービスの具体的な実装を作成すると、itがAPIプロバイダーを呼び出すことができます(単体テストの場合は、それをスタブで模擬できます)。
if (!apiTokenService.isTokenActive(token)) {
throw new AuthenticationException(ExceptionCodeType.TOKEN_NOT_ACTIVE);
}
(コードがないため申し訳ありませんが、Java(?)は私の強みではありません)
残念ながら、これらのことを行う方法の客観的な単一の真実はありません。それは常にDDDの解釈と、作業しているコンテキストに依存します。
1つの解釈では、Entitiesはデータホルダーまたはレコードにすぎず、Servicesまたはその他のサポートクラス。この解釈では、あなたのApiToken
にはisActive()
メソッドすらなく、代わりにすべてのデータを( getters を介して)発行し、他のクラスに処理を任せます彼らが好きなように。
ただし、オブジェクト指向のコンテキストで作業する場合は、解釈が大幅に異なる可能性があります。この場合、提案されたソリューションには2つの問題があります。
Strategy
オブジェクトは、ApiToken
内のすべてに完全にアクセスできる必要があります。言い換えれば、それらは非常に密に結合されます。これはOO世界では眉をひそめています。
Strategy
クラスはドメインの一部ではありません。開発者とビジネスの間で共有される語彙の一部ではありません。 ユビキタス言語 の一部ではありません。
私はあなたの要件のすべてを知らないという通常の免責事項で、これを行うことはどうですか:
_public interface ApiToken {
boolean isActive();
}
public final class DatabaseApiToken {
...
@Override
public boolean isActive() {
...sql or whatever...
}
}
_
これははるかに単純で、上記の両方の問題を解決し、DDDとOOの両方に対応しています。
また、whyを見て、メソッドisActive()
が必要です!時には(常にではありませんが)実際に単一のユースケースがあり、それ自体をintoApiToken
に移動できるため、 isActive()
は不要であり、ApiToken
にはより完全なロジックがあるため、これは良いことです。
これが オブジェクト指向ドメイン駆動設計 についての私のプレゼンテーションで、いくつかの追加ポイントがあります。