Order | |
---|---|
Id | Guid |
CustomerId | Guid |
ShippingAddress | String |
Placed | Bool |
Shipped | Bool |
OrderLine | |
---|---|
Id | Guid |
OrderId | Guid |
ProductId | Int |
Quantity | Int |
Order Created
→
Shipping Address Set
→
3 Lines Added
→
Line Removed
→
Order Placed
→
Order Shipped
class Order {
Guid Id;
Guid CustomerId;
String ShippingAddress;
Bool OrderPlaced;
Bool OrderShipped;
List<OrderLine> Lines;
public void Apply(OrderCreated e) {
Id = e.Id;
CustomerId = e.CustomerId;
}
public void Apply(LineAdded e) {
Lines.Add(new OrderLine(e.OrderLineId, /* ... */);
}
//etc
}
Given a function apply
apply :: State -> Event -> State
Current state is a left fold over previous events
foldl apply EmptyState events
Show me all orders placed in the last week
Return something OR mutate state. Never both.
//Command
void UpdateShippingAddress(string newAddress) {
if(_shipped)
throw new InvalidOperationException();
_shippingAddress = newAddress;
}
//Query - No mutation allowed!
int GetNumberOfLines() {
return _lines.count();
}
Command Query Responsibility Segregation
Given(
new OrderCreated(id, ...),
new ShippingAddressChanged(id, "123 Something Road, Somewhere")
)
.When(
new AddLineToOrder(id, ...)
)
.Expect(
new OrderLineAdded(id, ...)
);
Given(
new OrderCreated(id, ...),
new OrderDeleted(id)
)
.When(
new AddLineToOrder(id, ...)
)
.Expect<InvalidOperationException>();