Skip to content

Instantly share code, notes, and snippets.

@erikrozendaal
Created February 5, 2011 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikrozendaal/812684 to your computer and use it in GitHub Desktop.
Save erikrozendaal/812684 to your computer and use it in GitHub Desktop.
Code for immutable domain blog part 4
trait AggregateFactory[AR <: AggregateRoot[AR, Event], Event] extends EventSourced[Event] {
def loadFromHistory[T <: AR](history: Iterable[Event]): T = {
var aggregate = applyEvent(history.head)
for (event <- history.tail)
aggregate = aggregate.applyEvent(event)
aggregate.asInstanceOf[AR].markCommitted.asInstanceOf[T]
}
}
def applyEvent = {
// [... code omitted ...]
case event: InvoiceSent => applySent(event)
// [... code omitted ...]
}
Invoice.create(2).changeRecipient(Some("Erik")).pay.send.addItem("Food", 2.95)
sealed trait Invoice extends AggregateRoot[Invoice, InvoiceEvent]
case class DraftInvoice(
uncommittedEvents: List[InvoiceEvent],
id: Int,
recipient_? : Boolean = false,
nextItemId: Int = 1,
items: Map[Int, InvoiceItem] = Map.empty)
extends Invoice {
// [... code omitted ...]
}
"draft invoice" should {
val invoice: DraftInvoice = Invoice.loadFromHistory(Seq(InvoiceCreated(1)))
"not be payable" in {
invoice.pay must throwA[IllegalArgumentException]
}
}
case class PaidInvoice(uncommittedEvents: List[InvoiceEvent]) extends Invoice {
def markCommitted = copy(uncommittedEvents = Nil)
def applyEvent = unhandled
}
def send: SentInvoice = {
require(readyToSend_?, "recipient and items must be specified before sending")
val now = new LocalDate
applySent(InvoiceSent(id, sentDate = now, dueDate = now.plusDays(14)))
}
private def applySent(event: InvoiceSent) = new SentInvoice(event :: uncommittedEvents, id, event.dueDate)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment