Template method pattern with BPMN

We have a process where the default flow involves numerous UserTasks interleaved by ServiceTasks, where the ServiceTasks invoke a backend.

Now a use case has come up where we need to make the same backend calls, but not interleaved with UserTasks - in a way, “headless” execution.

A “naive” implementation would just model a second path which only consists of the service tasks.

In OO one could use the template method design pattern, i.e. write a template method in an abstract base class which invokes the services, and in between calls out to abstract methods that may or may not implement user interfaces.

Is there a way to achieve something similar in BPMN?

To illustrate the idea, I could have a flow which does everything, but instead of user tasks invokes CallActivities. The sub processes can either contain the user tasks or a noop process. The calledElement of the CallActivities would have to be an expression, so that the process could control in advance, if the noop or the UI subprocess should be called.

Almost there, but what I am actually looking for is a mechanism which corresponds to “implementing an abstract process”.

Hi @dschulten,

I would not go to make the process more complicated than it should be.

To think about abstract classes or patterns is OK for developers, but only a very few business people may understand this.

In BPMN the process is the one and only model and no further abstraction is avialable.

I think these are two alternative approaches for the headless processes:

It depends on the structure of your real process which way to follow.

Hope this helps, Ingo

1 Like

Thank you very much. Those are indeed the two obvious possibilities. In our case the model is a “technical” BPMN anyway, so we do not have to worry too much about readability for business people.

On the side of “more maintainable BPMN, less readable for Business People”, another possibility would be a multi-instance CallActivity which contains a sequence of UserTask and backend call.
I.e. we could loop over a list of descriptors which describe what to show to users and what to call. The “show to user” part would be guarded by a gateway, so that the descriptor can suppress the user task.
Just to mention it for the more convoluted minds :wink: