Common design patterns in IBM BPM / BAW with a sketch of each implementation (several are detailed in other answers on this site):
- Facade service per system - one toolkit service flow per external operation ("CRM: get customer"), input / output as business objects, errors normalised; BPDs never call an integration directly. Implementation: toolkit "CRM Connector" with a Server definition, external service, wrapper flows.
- Claim check - references instead of payloads in the process (question 2572).
- Constructor / initializer - first activity builds the complete business object (defaults, lookups).
- Configuration by EPV - thresholds and switches as EPVs read through one helper (question 766).
- Delayed response / request-callback - asynchronous integration with a message event and a timer escalation (question 1025).
- Correlated message events - UCA + intermediate message event with a business key (question 2573).
- Timer escalation ladder - timer boundary events on a user task: reminder at 2 days, reassign to manager at 5, auto-decision at 10; each timer path returns to the task via a gateway.
- Exception queue - errors caught by boundary events create a "Handle exception" task for an operations team with Retry / Skip / Abort decisions (question 2554).
- Saga / compensation - after a failed step, run compensating services in reverse order (a script keeps a list of completed steps; an event sub-process runs the compensations).
- Multi-instance work - "for each line item" sub-process with a completion condition, instead of loops with counters.
- Four-eyes approval - second approver must differ from the first: team filter service excluding tw.local.firstApprover.
- Dashboard + Service Call - CSHS dashboards that read through service flows, never SQL in the coach.
- Audit trail service - one toolkit service writes who / what / when to a table or the instance's comments; called from key activities.
// four-eyes: team filter service (input team TWTeam, output TWTeam) used by the "Second approval" activity
var out = new tw.object.Team(); out.name = tw.local.team.name; out.members = new tw.object.listOf.String();
for (var i = 0; i < tw.local.team.members.listLength; i++) {
if (tw.local.team.members[i] != tw.local.firstApprover) out.members.insertIntoList(out.members.listLength, tw.local.team.members[i]);
}
tw.local.filteredTeam = out;References