# Ch7. Modeling Workflows as Pipelines
---
### Review of the Place Order Workflow

---





---
### Transformation-oriented programming
Business processes can be thought of as a series of document transformations.
- fp: stateless and without side effects.

---
### The Workflow input
---
domain object (deserialized DTO)

---
### commands as input
sometimes the input is a command.
in order-placing system: the command - PlaceOrder

---
### Shared Common Fields Using Generics
There must be many commands which share fields in common.
OOP: base class; FP: generics
Define a command type contains:
1. common fields
2. a slot for the command-specific data

---
### Combine multiple cmds in one type
In some cases, all commands will be sent on one shared input channel.

The Sol: just a choice type contains all 3 commands

---
We just need a "routing" or "dispatching" input stage at the edge of bounded text (onion architecture).

---
### Modeling an Order as a set Of states
---
The Order is not just a static document.
How do we model this states?

---
### The Naive way
- create a record captures all states with flags

---
### Problems:
1. states are implicit and require lots of coditional code
2. some states contains data that is not needed for other states
3. no clear that which fields go with which flags
---
### A much better way
- create each type for each state of the order


---
### Final
create a top-level order type
this is the object that represent the order at any time in its life cycle.

---
Another advantage:
- new state can be added without breaking existing code.
---
### State Machines
---
A document or record can be in one or more states.

---
### Why use state machines ?
Benefits
- Each state has different allowable behaviors
- All states are explicitly documented.
- A design tool to force you to think.
---
### Implementation in F#
繼己看
---
### Modeling Each Step In the Workflow with Types
---
### The Validation Step
two dependencies:
- checkProductCodeExisted
- checkAddressExisted

---


---
With dependencies defined, we can now define the Validation Step as a function with:
- primary input: unvalidatedOrder
- two dependencies:
- checkProductCodeExisted
- checkAddressExisted
- output: validatedOrder
---
### The Pricing Step
Design the PriceOrder step

---


---
### The Acknowledge Order Step
create an acknowledgement letter and send it to customer

---
Q: What the content of the letter be ?
A: Another service function

---
We need to send it, but we don't care how here.

---
We should care about "is that ack sent?"
- simple way:

- better way:

or another service function
---
### Create the Events to return
a specific type:
- hard to add new events

---
### Better way
- define a placeOrderEvent


---
### Document Effects
---
What effects could the function have?
- an error?
- does it do I/O?
---
### Async and error effects
It's clear from the type signature that the function is doing I/O and that is might fail.

---
### Composing the workflow from the steps
---
When we have implementation for each step,
we should able to wire the output of the step to the input of the next one.
---

---
### Are dependencies part of design?
---
### Never a right answer
- for functions exposed in a public API, hide dependency information from callers
- for functions used internally, be explicit about their dependencies
---
### The complete pipeline
---
- input data
- input command
- output
- workflow definition
- internal steps
---

---

---

---

---

---
### Long-running workflows
---
if there are external services took much longer time to complete, how would it affect the design?
1. save the state into storage
2. break the original workflow into smaller, independent chunks
---

---
A Process Mananger is needed for much more complex cases.
1. handling incoming messages
2. determining what action should be taken
3. triggering the appropriate workflow

---
{"metaMigratedAt":"2023-06-15T11:12:28.073Z","metaMigratedFrom":"YAML","title":"DDD Ch.7","breaks":true,"description":"Ch7. Modeling Workflows as Pipelines","contributors":"[{\"id\":\"dc3885f0-42a0-4cef-b3d9-f3126ae04eec\",\"add\":8641,\"del\":2749}]"}