TL;DR

  • 集約は整合性の境界なので、合計金額のような派生値は、明細を更新する関数の中で一緒に更新する。
  • 集約は永続化の単位でもあり、集約ルートと子のエンティティは同じトランザクションで保存する。

内容

整合性の境界

第5章で見たように、集約は整合性の境界である。たとえば、注文の合計金額は各明細の金額の合計と同じでなければならない。

これを満たすには、値を保存せずに生データから計算するのが一番楽である。ただし、状況によっては追加のデータを永続化する必要もある。トップレベルの Order に AmountToBill を持たせる場合、データの整合性を保つため、どれかの明細が更新されたら合計も更新する。

let changeOrderLinePrice order orderLineId newPrice =
    let orderLine = order.OrderLines |> findOrderLine orderLineId
    let newOrderLine = { orderLine with Price = newPrice }
    let newOrderLines =
        order.OrderLines |> replaceOrderLine orderLineId newOrderLine
    let newAmountToBill = newOrderLines |> List.sumBy (fun line -> line.Price)
    let newOrder = {
        order with
            OrderLines = newOrderLines
            AmountToBill = newAmountToBill
    }
    newOrder

永続化の単位

集約は永続化の単位でもある。Order を RDB に保存するときは、Order 自身と各 OrderLine を同じトランザクションで挿入・更新しなければならない。

キーワード