Scala的event-sourced和CQRS案例程式碼

banq發表於2012-10-29
eligosource/eventsourced-example · GitHub

案例原理圖:

Scala的event-sourced和CQRS案例程式碼


個人目前觀點:其領域模型的領域事件程式碼好像比較複雜,幾乎是IF-ELSE這種條件判斷模板,作者不能重構得好看一些嗎?:

case class Invoice(
    id: String,
    items: List[InvoiceItem] = Nil,
    discount: Option[BigDecimal] = None,
    sentTo: Option[InvoiceAddress] = None) extends EventSourced[InvoiceEvent, Invoice] {

  def addItem(item: InvoiceItem): Update[InvoiceEvent, Invoice] = ...
  def setDiscount(discount: BigDecimal): Update[InvoiceEvent, Invoice] = ...
  def sendTo(address: InvoiceAddress): Update[InvoiceEvent, Invoice] = ...

  def handle(event: InvoiceEvent): Invoice = event match {
    case InvoiceItemAdded(_, item)       => copy(items = item :: items)
    case InvoiceDiscountSet(_, discount) => copy(discount = Some(discount))
    case InvoiceSent(_, to)              => copy(sentTo = Some(to))
  }
}

sealed trait InvoiceEvent extends Event { def invoiceId: String }
case class InvoiceItemAdded(invoiceId: String, item: InvoiceItem) extends InvoiceEvent
case class InvoiceDiscountSet(invoiceId: String, discount: BigDecimal) extends InvoiceEvent
case class InvoiceSent(invoiceId: String, to: InvoiceAddress) extends InvoiceEvent
<p class="indent">


在其Service中事件消費者部分程式碼:

 def receive = {
    case CreateInvoice(invoiceId) =>
      process(createInvoice(invoiceId)) { invoice =>
        emitter("listeners") sendEvent InvoiceCreated(invoiceId)
      }
    case AddInvoiceItem(invoiceId, expectedVersion, invoiceItem) =>
      process(addInvoiceItem(invoiceId, expectedVersion, invoiceItem)) { invoice =>
        emitter("listeners") sendEvent InvoiceItemAdded(invoiceId, invoiceItem)
      }
    case SetInvoiceDiscount(invoiceId, expectedVersion, discount) =>
      process(setInvoiceDiscount(invoiceId, expectedVersion, discount)) { invoice =>
        emitter("listeners") sendEvent InvoiceDiscountSet(invoiceId, discount)
      }
    case SendInvoiceTo(invoiceId, expectedVersion, to) =>
      process(sendInvoiceTo(invoiceId, expectedVersion, to)) { invoice =>
        emitter("listeners") sendEvent InvoiceSent(invoiceId, invoice, to)
      }
    case InvoicePaymentReceived(invoiceId, amount) =>
      process(payInvoice(invoiceId, None, amount)) { invoice =>
        emitter("listeners") sendEvent InvoicePaid(invoiceId)
      }
  }
<p class="indent">



Scala的Eventsourced庫包使用介紹

[該貼被banq於2012-10-29 10:30修改過]

相關文章