软糖

fp-ddd chapter 5

Domain Modeling Made Functional - Chapter 4

Domain Modeling with Types

we’re using a namespace in F# to indicate a DDD bounded context

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
namespaceOrderTaking.Domain
type Undefined = exn
type WidgetCode = WidgetCode of string
type GizmoCode = GizmoCode of string
type ProductCode =
| Widget of WidgetCode
| Gizmo of GizmoCode
type UnitQuantikty = UnitQuantity of int
type KilogramQuantity = KilogramQuantity of decimal
type OrderQuantity =
| Unit of UnitQuantity
| Kilos of KilogramQuantity
type OrderId = Undefined
type OrderLineId = Undefined
type CustomerId = Undefined
type CustomerInfo = Undefined
type ShippingAddress = Undefined
type ShippingAddress = Undefined
type BillingAddress = Undefined
type Price = Undefined
type BillingAmount = Undefined
type Order = {
Id: OrderId // id for entity
CustomerId: CustomerId ​// customer reference
ShippingAddress: ShippingAddress
BillingAddress: BillingAddress
OrderLines: OrderLInt list
AmountToBill: BillingAmount
}
and OrderLine = {
Id: OrderLineID // id for entity
}

Workflow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// input
type UnvalidatedOrder = {
OrderId: string
CustomerInfo: ...
ShippingAddress: ...
}
// output
type PlaceOrderEvents = {
AcknowledgmentSent: ...
OrderPlaced: ...
BillableOrderPlaced: ...
}
// Errors
type PlaceOrderError =
| ValidationError of ValidationError list
| .. // other errors
and ValidationError = {
FieldName: string
ErrorDescription: string
}
// The "place order" process
type PlaceOrder =
UnvalidatedOrder -> Result<PlaceOrderEvents, PlaceOrderError>