2017-01-12 4 views
6

私はグレッグヤングイベントソーシングに話を見てきましたが、私は、ビジネスロジックがに収まるところへと困惑している簡単な例:。Event Sourcing - ドメインロジックはどこに適合しますか?

1) Shopping Cart Created 
2) Item Added 
3) Item Added 
4) Promotional Code - 20% Off 

プロモーションコードは、ショッピングカートのアイテムに対して計算され、その結果をイベントとして格納します。私は "PromotionalCodeAddedEvent"が理にかなっていると理解していますが、数学はどこで行われますか?私は考えています:

結果はどこにも終わらず、読み込みモデルは計算を実行する必要があります。

私はコンセプトを完全に理解していません。どんな助けも素晴らしいでしょう。

+0

は、次の擬似コードを考えてみましょう。あなたはそれをここに見ることができます[CQRS + Event Sourcing - ステップバイステップの概要](http://danielwhittaker.me/2014/10/02/cqrs-step-step-guide-flow-typical-application/) – Codescribler

答えて

1

たとえば、計算結果を含むPromotionalCodeAppliedなどの2番目のイベントを発生させることができます。

読み込みモデルは、あらかじめ計算された結果を使用するだけです。

+0

こんにちはアレクサンダーしたがって、各Itemが追加された後、ItemAddedEventにもショッピングカートの全価格が含まれますか? – TBD

+0

はい、これは機能しますが、別の "ShoppingCardTotalPriceChanged"イベントを使用することもできます。これはアイテムまたはプロモーションコードが追加されたときに発生します。 –

0

ここでは、コマンドメソッドからイベントを返すのが好きです。アレクサンダー・ランガーが述べたように、あなたは「数学」を適用すると、関連するイベント(複数可)を返したい:

public PromotionalCodeApplied AddPromotionalCode(PromotionalCode code) 
{ 
    //perform calculation against shopping cart items. 
    var promotionalCodeApplied = new PromotionalCodeApplied(code.VoucherNumber, discountAmount, DateTime.Now); 

    On(promotionalCodeApplied); 

    return promotionalCodeApplied; 
} 

public void On(PromotionalCodeApplied promotionalCodeApplied) 
{ 
    _voucherNumber = promotionalCodeApplied.VoucherNumber; 
    _discountAmount = promotionalCodeApplied.DiscountAmount; 
    _discountDate = promotionalCodeApplied.DateAppllied; 
} 

今すぐあなたの読み込みモデルは、関連する値へのアクセス権を持っています。

3

プロモーションコードと同じように単純なものは、実際にはかなり複雑な使用例です。主に、これはプロモーションコードが(通常は)1人以上のビジネスユーザーによって管理されるロジックであり、ドメイン自体の内部にも存在するという事実によるものです。その意味で非伝統的です。これを処理する方法はいくつかありますが、私が概説するのは私の個人的なアプローチです。議論の便宜上

、次のような知られているプロモーションコード、単純な一連の持っていることを前提としています

  • $ Xオフ買い物や最低購入
  • なし
    • 購入オフX%を、最低購入

    の有無にかかわらず我々としても、いくつかの仮定を行うことができます。

    • APをromotionalコードはAプロモーションコードは、終了日

    を持って

  • 開始日は、プロモーションコードの適用が難しいことができます。私たちが定義した2つのシナリオを考えてみましょう。 「$ Xオフ購入」は固定金額なので比較的簡単です。しかし、 "X%オフ購入"は、より複雑です。固定金額のみの場合は、しきい値に達するとすぐに割引をカートに適用することができます。パーセンテージベースの割引で、ユーザーが2つのアイテムを追加し、プロモーションコードを追加してから別のアイテムを追加すると、プロモーションはすでに「適用済み」になります。

    このため、個人的には、プロモーションコードをカートに「添付」するだけです。どうして?その理由は、チェックアウトの時点で、カートを使用して注文を生成すると想定できる可能性が高いからです。その時間まで、カートの内容物は流動的である。カートに対するユーザーの行動は、固定金額以外の割引額を仮定して、カートの合計金額と合計割引額を変更します。また、ユーザーがカートから1つまたは複数のアイテムを削除し、カートを合計した値がしきい値を下回って割引を適用した場合、割引を無効としてレンダリングすることもできます。

    だから、私は実際には複数のコマンドを含んでいました。基本的にカートの価値に影響を与えるコマンドは、割引額を変更する可能性があります。

    • カート
    • からアイテムを削除することでアイテムの数量を変更
    • カート
    • に項目を追加します。そのために、私はコマンドのために再計算される割引額を探していますカート
    • は、これらすべてのでカート

    に添付カート

  • 変更プロモーションコードにプロモーションコードを追加しますoperatあります私はカートに含まれるデータの参加を得て、プロモーションコード自体の中で割引を計算しています。 は、プロモーションコードのようにがこのパスに沿って集計されるように感じます。だから、私はコマンドハンドラが、必要な情報をカートに提供できるドメインサービスを呼び出させるようにします。そのドメインサービスはプロモーションコードをロードする予定で、そのカート内の広告申込情報を渡すことができるので、プロモーションコードで計算された割引がどのようなものになるかがわかります。次に、カートの新しい値と調整値(割引)を含むイベントを生成します。この経路を経て、カート内の広告申込情報に基づいて割引を計算するロジックは、プロモーションコードの責任で行われます。

    代わりに、この責任をカートに入れることができます。しかし、個人的には、プロモーションコード内のドメインロジックのカプセル化自体がより理にかなっているように感じます。私はあなたがカートから注文を生成する可能性が高いと述べました。プロモーションコードを集計にし、広告申込情報に基づいて割引を適用するロジックを含むことで、広告申込情報の割引を計算する方法(カートまたは注文の条件

  • +1

    ジョセフ、いいアイデアと思考のための食べ物を与えてくれた応答に感謝します。 – TBD

    1

    私は "PromotionalCodeAddedEvent"が理にかなっていると思いますが、数学はどこで行われますか?

    ショッピングカートの変更を行うコマンドで発生します。このようなコマンドはすべて、すべてのビジネスロジックがホストされるRecalculateTotals()のようなメソッドを呼び出します。それが役に立つなら、私は典型的なCQRSとESアプリケーションをレイアウトし、それが一緒にどのように適合するかブログの記事を持っている

    public void AddPromotionalCode(PromotionalCode code) 
    { 
        var @event = new PromotionalCodeAdded(code); 
        var amount = RecalculateTotalAmount(extraEvent: @event); 
        @event.TotalAmount = amount; 
        _eventStore.Publish(@event); 
    } 
    
    decimal RecalculateTotalAmount(IEvent extraEvent) 
    { 
        var relatedEventTypes = new[] { typeof(PromotionalCodeAdded), typeof(ShoppingCartCreated), typeof(ItemAdded) }; 
        var events = _eventStore.ReadEventsOfTypes(relatedEventTypes); 
        var events = events.Concat(new[] { extraEvent }); 
    
        //calculation logic goes here based on all related events 
    } 
    
    関連する問題