When creating a solution, much of thinking goes into the creation of functional chunks, database tables and generation of reports. Basically, the definition is made part by parts, and then it is all glued together.
Now, how do you glue it? At architectural level, it is important (and often overlooked) to define a flow strategy. What is that? Well, all the functional elements will have to execute at some time, and the execution may have at least start and one end. But before and after that what happens? How do you get to that start, and what do you after the end?
At one particular moment, the application may be doing several things, all coordinated. At the next moment some things will continue, other will stop and other will start. That “movement” is the flow, which is important. Think two applications with the exact same elements, but with different flows: they will behave differently, and even produce different things!
So, which flow strategies are there? Of course, your actual application does have one, maybe you don’t it yet but there it is, just like an undocumented architecture. Let’s review some of the strategies:
-> The Script. In this strategy, there is one script, like in the movies, where all is described: from the start, the time when one actor cries and the way another actor jumps out of the window. And there is a director, who is in charge of telling the actors what to do. Notice that the actors (architectural element, components, or even plain objects) know what to do and they do it, but the time when they must act, and the decision of who is next, is the director’s job. And this can be hierarchical, where one higher director will control other directors, which in turn control the actors.
Another important thing is the director may know all. That is, there is a continuum manager (the director or a helper). Meaning the state, persisted or not, is taken care of by the directional staff, and not by the actors.
This is perfect for concurrent processing, with highly pluggable and independent pieces of code.
-> The Production Line. If you center the flow on the processed entity, then you can have a production line. Here, the entity goes from one station to the next one, following one sequence (with forks in some parts and sub-roads). You recall the Pipes-and-filters here. The flow is actually very static, predefined. There are decision in the way too. The state in this case is managed by the actual entity, and in some cases you may need to avoid state at all.
-> Democratic Control (Chained, Distributed). This is a very common setting: the flow is in the actual executed code. That is, one piece of code not only executes its task, but also knows which other piece is called next. Of course, this means coupling and a bad separation of concerns. A change in the flow will require changes in the business code. Despite this, it is commonly used by developers (without much thinking in the strategy).
It may be use in very simple cases, with a very static flow, where the construction of a more complex flow strategy may not be worth it.
-> Workflow (or control container). Usually it uses orchestrators (I prefer to call them directors) in an engine, which will parse and interpret the flow. It seems similar to the Script, but here the engine is a generic orchestrator that executes a flow, instead of a functional element programmed with the flow itself. It is more flexible as a change to the flow may require simple adjusting the flow definition. The engine will not suffer modifications.
This is the regular workflow solutions out there, like WFF and the tools using BPEL.
The problem with this is that you require a control container, an engine to execute the flow.
-> Reactive (Event Driven). The other strategy is similar to the democratic control, as the control is associated to the functional pieces. Here, the pieces are no chained, and the control may be an aspect. Each piece is passive but listening to the environment, until something happens. Then, some pieces may decide to act, and perform something. That performance may be also detected by others, and so on. These are event driven systems, where there is an event engine and the pieces are the ones that act upon messages or events. Note the control here is in the pieces, not the engine.
So, now: which flow strategy do you use?