3

私はまだDDDアプリケーションにかなり慣れていません。私はEricEvanの「ドメイン駆動設計」を読んでいて、UdiDahanによるドメインイベント救済によるドメインモデルパターンの採用を読んだことがあります...

しかし、私が理解できないことの1つは、ドメインイベントの正常な完了または失敗した完了に関する情報を、ユーザー(つまり、UIレイヤー)へのフィードバックとしてどのように返す必要があるかということです。

たとえば、次のアプリケーション層コードを使用できます。

// Application Layer
public void SubmitOrder(OrderData data)
{ 
  var customer = GetCustomer(data.CustomerId);
  var shoppingCart = GetShoppingCart(data.CartId);
  customer.Purchase(shoppingCart);
}

// Domain Model
public class Customer
{ 
   public void Purchase(ShoppingCart cart)
   {
      // something done with the cart...

      DomainEvents.Raise(new CustomerPurchaseCompleted() { Customer = this, ShoppingCart = cart });
   }
}

ここで、顧客が指定された電子メールアドレスを持っている場合に、顧客に確認電子メールを送信する次のイベントハンドラーがあるとします。

public class CustomerPurchaseCompletedHandler : Handles<CustomerPurchaseCompleted>
{ 
   public void Handle(CustomerPurchaseCompleted args)
   {
      if (args.Customer.Email != null) {
         // send email to args.Customer
      }
      else {
         // report that no email will be sent...
      }
   }
}

私の質問は、顧客が電子メールを設定していないために電子メールが送信されないというフィードバックメッセージをUIレイヤーに「バブルアップ」するにはどうすればよいですか?

私が今日見ているオプションは、次のようなものです。

  1. UIレイヤーに、顧客が電子メールを持っているかどうかを確認し、それに応じてメッセージに対応してもらいます。UIは、アプリケーションレベルの情報である電子メールが送信されることになっていることを認識しているため、これは悪いようです。

  2. UserHasNoEmailException電子メールが存在しないときにをスローし、その情報をどこかでキャッチします。情報を返すために例外を使用するべきではなく、致命的なエラーではなく、他のハンドラーを中止するべきではないため、これは本当に悪いことです...

  3. いくつかSubmitOrder()返品してList<FeedbackMessage>ください。これには、このリストも返すようにメソッドPurchase()とメソッドを変更する必要があります。DomainEvents.Raise()これにより、ドメインモデルはUIが表示されるべきではないことを認識します...

これらの3つのオプションはどちらも、実際には適切で実用的ではないようです。では、DDDの専門家はどのようにそれを行うのでしょうか?

ありがとう。

4

2 に答える 2

1

別のオプションは、顧客が電子メールアドレスを持っていないことをUIに通知することを特に担当する別のイベントハンドラーを実装することです。したがって、CustomerPurchaseCompletedHandlerが電子メールを送信しない場合、このハンドラーはUIに通知します。このハンドラーはUIレイヤーの一部になります。UIに通知する良い方法は、このハンドラーにイベントアグリゲーターを挿入することです。

public class NotifyingCustomerPurchaseCompletedHandler : Handles<CustomerPurchaseCompleted>
{ 
   public IEventAggregator Events { get; set; }

   public void Handle(CustomerPurchaseCompleted args)
   {
      if (args.Customer.Email == null) {
         // notify UI
         this.Events.GetEvent....
      }
   }
}

全体として、これは基本的にアプローチ1です。確かに、UIレイヤーは電子メールが送信されることを認識していますが、電子メールが送信されないことを示すメッセージをレンダリングする必要があるため、UIはその知識を持っている必要があります。メッセージの表示はUIの問題であり、ハンドラーの実装をUIレイヤーの一部として残すことで、メッセージをそのまま保持します。このアプローチの問題は、顧客が2回メールを受け取っているかどうかを確認していることです。さらに、電子メールの送信はUI通知に直接結び付けられていません。

別のオプションは、電子メールを持っていない顧客の購入が完了したことを示す別のイベントを導入することです。その後、UIはこのイベントをサブスクライブできます。このアプローチの欠点は、ドメイン知識を表現しないというUI要件専用のイベントを作成していることです。

于 2012-11-14T18:20:24.280 に答える
0

イベントはフィードバックを報告するべきではありません。イベントはフィードバックです。

この場合、Emailはビジネス要件です。したがって、customer.Purchase(shoppingCart);電子メールが指定されていない場合は、実際に例外をスローする必要があります。

しかし、実際の電子メール配信が失敗したとしましょう。私が通常行うことは、通知に使用するドメインモデルを作成することです。だから私はこれをします:

var notification = new Notification(userId, "Failed to deliver receipt to user.");
notificationRepository.Save(noitification);

NotificationCreatedこれにより、UIで取得できるイベントが生成されます。

于 2012-11-15T09:20:08.323 に答える