1

私はシステムを設計するためにドメイン駆動設計規則に従っています。サービス、外部システム、検証について疑問があります。

アグリゲートは、他のシステムのWebサービスと対話して、検証を行い、情報を提供する必要があります。アグリゲートが外部の単語にアクセスできるようにするのが良い考えかどうかはわかりません。外部サービスにアクセスするためのサービスを作成すると、不変条件と検証を適用するのに問題があります。すべてのロジックを集約に入れると、良い考えには聞こえませんが、これらの問題は解消されたようです。

問題を理解しやすくするために、ユーザーアグリゲートがあり、電子メールが正しいことを確認するために電子メールを送信する必要があるとします(私の実際の問題では、外部のWebサービスと通信する必要があります)

public class User {
    public User (Long id, String name, String email) {...}
    public changeEmail(String newEmail) {...}
    ...
}

public interface EmailValidatorService {
    /**
    * Sends a test email
    */
    public verifyEmail(String email) throws EmailException;
}

これが良いアイデアなのか、それともメール検証ロジックをユーザーアグリゲートの一部にするべきなのかはわかりません。おそらくそれはサービスであり、Useraggregateがそれを使用する可能性があります...しかしそれも良い考えのようには思えません。

それがユーザー集合体の一部である場合、それは追加の責任を負い、それがサービスである場合、ドメインルールを適用する簡単な方法がわかりません。¿開発者がサービスで検証せずにchangeEmailを使用した場合はどうなりますか?

4

1 に答える 1

3

このシナリオを実装するには、いくつかのオプションがあります。1つは、この特定のユースケースを処理するアプリケーションサービスに検証機能を呼び出させることです。

class UserService
{
  EmailValidatorService emailValidatorService;
  UserRepository userRepository;

  public void changeUserEmail(string currentEmailAddress, string newEmailAddress)
  {
    var user = this.userRepository.GetByEmail(currentEmailAddress);
    if (user == null)
       throw ...;


    this.emailValidatorService.verifyEmail(newEmailAddress);

    user.changeEmail(newEmailAddress);

    // commit, etc...
  }
}

アプリケーションサービスは、この種の検証ルールを挿入するのに便利な場所です。外部サービスへの呼び出しが必要な種類、またはアグリゲートが簡単にアクセスできないサービスです。より一般的には、アプリケーションサービスは、純粋なDDDアプローチが完全に適合しない場合を処理するための一種の「フォールバック」メカニズムである可能性があります。また、ドメインモデルを使用するか、トランザクションスクリプトのようなものを使用するかに関係なく、アプリケーションサービスが存在する可能性があります。

もう1つのオプションは、UserクラスのchangeEmailメソッドでアグリゲートにバリデーターを提供することです。

class User
{
  string emailAddress;

  public void changeEmail(string newEmailAddress, EmailValidatorService validator)
  {
    validator.verifyEmail(newEmailAddress);
    this.emailAddress = newEmailAddress;
  }
}

ここでの利点は、アグリゲートが電子メールアドレスの変更に関連するすべてのロジックをカプセル化することです。その結果、クライアントコードは、バリデーターを提供せずに電子メールアドレスを変更することはできません。これは、アプリケーションサービスのアプローチでは適用できません。また、これは、依存性注入を介してバリデーターサービスを参照するユーザーアグリゲートとは異なります。代わりに、これは一種のオンザフライの依存性注入です。

この特定のシナリオで考慮すべきもう1つのことは、実行したい検証の性質です。1つの特徴は、電子メールアドレスがある時点で有効である場合、将来は無効になる可能性があることです。これは、無効な電子メールアドレスを持つ既存のユーザーを処理するためのワークフローをすでに用意している必要があることを意味します。そのロジックがすでに配置されている場合、ドメインでの検証を保証することに煩わされるのはなぜですか?結局のところ、バリデーターサービスが電子メールアドレスが有効でアクティブであることを保証したとしても、ユーザーがそれにアクセスするという保証はありません。

于 2012-10-01T18:56:27.413 に答える