As you already know, there are multiple ways to express any given core business concept in the code via domain modeling (we discussed this topic in previous article). These ways usually depend on the architecture style selected for the bounded context, in which we are currently working.
For now, let’s focus on one of such domain concepts: long-running business processes.
In a cloud-based SaaS company, we could have following business processes (among many other):
- if invoice has a non-zero amount and was not paid within 15 days, then send customer a reminder.
- if customer balance stays below -5EUR for more than 30 days, then issue a lockdown.
- if distributed computing process has not finished processing all data batches within 1 hour, then restart it once (except cases, when it was already restarted - then issue a termination alert)
As you probably already noticed, these examples share a few similarities:
- they are aware of the passing of time and deal with it;
- these processes express rather complex precondition that is based on current state of the system and leads to one or more
Let’s assume that we are dealing with a distributed system, where information about current state is shared with events. In such case, our business process might resemble a piece from complex event processing and would look this from the logical perspective:
How can we implement this “Business Process” box? There are multiple alternatives, depending on the architecture style you have chosen.
For example, you can use a state machine, where each instance of state machine would correspond to a specific process instance that you are tracking. Events would then be used to navigate an instance of the state machine across the nodes. It will also use external timer service to send messages “to future” (where message is put on hold till certain time comes).
State machines are good for formalized domains. You can learn more about such approaches in the materials provided by Gregory Young and Udi Dahan.
However, when we are dealing with business processes, that are rich with fuzzy logic, uncertainty and also happen to evolve rapidly, then a more simple solution might be needed. Especially, when you have almost no development time to spare.
What is the most simple solution in case with locking customer balance for overdrafts? For instance, we can project all events to a view, which will track all active customers that used our services and went below the threshold at some point. Then our execution will be responsible for regularly checking this view and sending “Lockdown” to every customer that had his balance below the threshold for too long.
This component would also need to keep in mind that certain customers require special handling and investigation before being locked out, while others can be locked right away. Naturally, these rules will be changing really often.
What is the fastest and most flexible way to implement such component in a rapidly growing and changing environment?
You simply wire view to the UI, attach a button to send “lockdown command” and ask a person from the business department to spend half an hour per week processing all late customers. This will save dev department hours on implementing these complex execution rules, testing them and then changing (as business discovers new corner cases). Essentially we let the rules evolve and change in the environment that shapes them: in the minds of business managers.
In other words, at this point we avoid large development effort with a little bit of human time.
Please, keep in mind, that once business processes are established and we have so many cases, that manually processing them takes too much time (that should be a profitable company by then), we can always rewrite these lockdown rules as a continuously running server-side task (rules would be mostly established by then). We could still keep the projection and a corresponding view.
At this point we invest a fixed amount of development to automate a large portion of manual work.
This gradual evolution of business processes is currently the recommended approach within Lokad.CQRS architecture style for delivery of non-formalized and rapidly changing business rules.