As we discussed earlier, we would ideally like all our functions to be “pure,” which makes them easier to reason about and test. Functions that read from or write to the outside world cannot be pure, so when designing our workflows, we want to avoid any kind of I/O or persistence-related logic inside the workflow. This generally means separating workflows into two parts:
For example, let’s say we have a workflow that implements the logic for paying an invoice. In a model that mixes up domain logic and I/O, the implementation might be designed like this:
Load the invoice from the database.
Apply the payment. ...