BPMN Basics: Process Modeling with Events, Gateways, Tasks, Pools & Lanes
This article is a comprehensive introduction to BPMN basics – including process modeling with events, gateways, tasks, pools and lanes with practical examples.
In a Nutshell
BPMN (Business Process Model and Notation) is a standardized notation for modeling business processes with graphical elements such as events, gateways, tasks and swimlanes.
Compact Technical Description
BPMN (Business Process Model and Notation) is a graphical standard for describing business processes. It enables a uniform representation of process flows regardless of tools and organizations.
Important BPMN Elements:
Events
- Start Event: Process start (circle, thin border)
- End Event: Process end (circle, thick border)
- Intermediate Event: Intermediate event (circle, double border)
- Boundary Event: Error event on task
- Timer Event: Time-driven events
- Message Event: Message-based events
Tasks
- User Task: Manual task by user
- Service Task: Automated task
- Script Task: Script execution
- Manual Task: Manual task without system support
- Receive Task: Wait for message
- Send Task: Send message
Gateways
- Exclusive Gateway: Exclusive branching (X)
- Parallel Gateway: Parallel execution (+)
- Inclusive Gateway: Inclusive branching (O)
- Complex Gateway: Complex conditions
- Event Gateway: Event-based branching
Swimlanes
- Pool: Process container for an organization
- Lane: Area of responsibility within a pool
- Participant: Actor in the process
Exam-Relevant Key Points
- BPMN: Standardized process modeling notation
- Events: Process events (Start, End, Intermediate)
- Tasks: Process tasks (User, Service, Script)
- Gateways: Process branching (Exclusive, Parallel, Inclusive)
- Pools/Lanes: Organizational assignment (Swimlanes)
- Sequence Flow: Process flow between elements
- Message Flow: Communication between pools
- IHK-relevant: Important for business process analysis and optimization
Core Components
- Events: Process control through events
- Tasks: Execution of work steps
- Gateways: Decisions and branches
- Pools: Process containers for organizations
- Lanes: Areas of responsibility
- Sequence Flow: Process flows
- Message Flow: Inter-process communication
- Artifacts: Additional information (data objects, groups)
Practical Examples
1. BPMN Process: Order Processing
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://www.example.com/bpmn">
<!-- Prozess: Bestellabwicklung -->
<process id="bestellprozess" name="Bestellabwicklung" isExecutable="false">
<!-- Start Event -->
<startEvent id="start_bestellung" name="Bestellung eingegangen"/>
<!-- User Task: Bestellung prüfen -->
<userTask id="pruefe_bestellung" name="Bestellung prüfen">
<documentation>
Mitarbeiter prüft Bestellung auf Vollständigkeit und Verfügbarkeit
</documentation>
</userTask>
<!-- Exclusive Gateway: Bestellung gültig? -->
<exclusiveGateway id="gueltig_pruefung" name="Bestellung gültig?"/>
<!-- Service Task: Lager prüfen -->
<serviceTask id="pruefe_lager" name="Lagerbestand prüfen">
<documentation>
Automatisierte Prüfung der Lagerverfügbarkeit
</documentation>
</serviceTask>
<!-- Parallel Gateway: Parallelverarbeitung -->
<parallelGateway id="parallel_start" name="Parallel starten"/>
<!-- User Task: Rechnung erstellen -->
<userTask id="erstelle_rechnung" name="Rechnung erstellen">
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>finanzabteilung</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<!-- Service Task: Ware versenden -->
<serviceTask id="versende_ware" name="Ware versenden">
<documentation>
Automatisierter Versand über Logistiksystem
</documentation>
</serviceTask>
<!-- Parallel Gateway: Zusammenführen -->
<parallelGateway id="parallel_end" name="Zusammenführen"/>
<!-- End Event: Bestellung abgeschlossen -->
<endEvent id="end_erfolgreich" name="Bestellung abgeschlossen"/>
<!-- End Event: Bestellung abgelehnt -->
<endEvent id="end_abgelehnt" name="Bestellung abgelehnt"/>
<!-- Sequence Flows -->
<sequenceFlow sourceRef="start_bestellung" targetRef="pruefe_bestellung"/>
<sequenceFlow sourceRef="pruefe_bestellung" targetRef="gueltig_pruefung"/>
<sequenceFlow sourceRef="gueltig_pruefung" targetRef="pruefe_lager">
<conditionExpression xsi:type="tFormalExpression">${bestellungGueltig == true}</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="gueltig_pruefung" targetRef="end_abgelehnt">
<conditionExpression xsi:type="tFormalExpression">${bestellungGueltig == false}</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="pruefe_lager" targetRef="parallel_start"/>
<sequenceFlow sourceRef="parallel_start" targetRef="erstelle_rechnung"/>
<sequenceFlow sourceRef="parallel_start" targetRef="versende_ware"/>
<sequenceFlow sourceRef="erstelle_rechnung" targetRef="parallel_end"/>
<sequenceFlow sourceRef="versende_ware" targetRef="parallel_end"/>
<sequenceFlow sourceRef="parallel_end" targetRef="end_erfolgreich"/>
</process>
</definitions>
2. BPMN with Java Implementation
import java.util.*;
import java.time.*;
// BPMN Process Engine (simplified)
class BPMNProcessEngine {
private Map<String, BPMNElement> elements = new HashMap<>();
private Map<String, List<String>> sequenceFlows = new HashMap<>();
private Set<String> completedElements = new HashSet<>();
private Map<String, Object> processVariables = new HashMap<>();
public void addElement(BPMNElement element) {
elements.put(element.getId(), element);
}
public void addSequenceFlow(String from, String to) {
sequenceFlows.computeIfAbsent(from, k -> new ArrayList<>()).add(to);
}
public void setVariable(String name, Object value) {
processVariables.put(name, value);
}
public Object getVariable(String name) {
return processVariables.get(name);
}
public void executeProcess(String startElementId) {
System.out.println("=== BPMN Process Start ===");
executeElement(startElementId);
}
private void executeElement(String elementId) {
if (completedElements.contains(elementId)) {
return;
}
BPMNElement element = elements.get(elementId);
if (element == null) {
throw new RuntimeException("Element not found: " + elementId);
}
System.out.println("\n--- Execute: " + element.getName() + " (" + elementId + ") ---");
// Execute element
element.execute(this);
completedElements.add(elementId);
// Find next elements
List<String> nextElements = sequenceFlows.get(elementId);
if (nextElements != null) {
for (String nextId : nextElements) {
executeElement(nextId);
}
}
}
}
// BPMN Element Interface
interface BPMNElement {
String getId();
String getName();
void execute(BPMNProcessEngine engine);
}
// Event Implementations
class StartEvent implements BPMNElement {
private String id;
private String name;
public StartEvent(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("Process started: " + name);
engine.setVariable("startTime", LocalDateTime.now());
}
}
class EndEvent implements BPMNElement {
private String id;
private String name;
public EndEvent(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("Process ended: " + name);
engine.setVariable("endTime", LocalDateTime.now());
Duration duration = Duration.between(
(LocalDateTime) engine.getVariable("startTime"),
(LocalDateTime) engine.getVariable("endTime")
);
System.out.println("Process duration: " + duration.toSeconds() + " seconds");
}
}
// Task Implementations
class UserTask implements BPMNElement {
private String id;
private String name;
private String assignee;
public UserTask(String id, String name, String assignee) {
this.id = id;
this.name = name;
this.assignee = assignee;
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("User Task assigned to: " + assignee);
System.out.println("Task: " + name);
// Simulate user interaction
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("User Task completed");
engine.setVariable("userTask_" + id + "_completed", true);
}
}
class ServiceTask implements BPMNElement {
private String id;
private String name;
private String serviceClass;
public ServiceTask(String id, String name, String serviceClass) {
this.id = id;
this.name = name;
this.serviceClass = serviceClass;
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("Service Task: " + name);
System.out.println("Service class: " + serviceClass);
// Simulate service call
if (serviceClass.equals("LagerService")) {
boolean verfuegbar = checkLagerverfuegbarkeit(engine);
engine.setVariable("lagerVerfuegbar", verfuegbar);
System.out.println("Inventory availability: " + verfuegbar);
} else if (serviceClass.equals("RechnungService")) {
String rechnungsNummer = generateRechnung(engine);
engine.setVariable("rechnungsNummer", rechnungsNummer);
System.out.println("Invoice created: " + rechnungsNummer);
}
}
private boolean checkLagerverfuegbarkeit(BPMNProcessEngine engine) {
// Simulate inventory check
return Math.random() > 0.3; // 70% availability
}
private String generateRechnung(BPMNProcessEngine engine) {
return "RG-" + System.currentTimeMillis();
}
}
// Gateway Implementations
class ExclusiveGateway implements BPMNElement {
private String id;
private String name;
private Map<String, String> conditions;
public ExclusiveGateway(String id, String name) {
this.id = id;
this.name = name;
this.conditions = new HashMap<>();
}
public void addCondition(String targetId, String condition) {
conditions.put(targetId, condition);
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("Exclusive Gateway: " + name);
// Evaluate condition
boolean bestellungGueltig = (boolean) engine.getVariable("bestellungGueltig");
System.out.println("Condition 'bestellungGueltig': " + bestellungGueltig);
// Make decision
if (bestellungGueltig) {
engine.setVariable("gateway_decision_" + id, "gueltig");
} else {
engine.setVariable("gateway_decision_" + id, "ungueltig");
}
}
}
class ParallelGateway implements BPMNElement {
private String id;
private String name;
public ParallelGateway(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String getId() { return id; }
@Override
public String getName() { return name; }
@Override
public void execute(BPMNProcessEngine engine) {
System.out.println("Parallel Gateway: " + name);
if (name.contains("starten")) {
System.out.println("Parallel execution started");
engine.setVariable("parallel_branches_active", true);
} else {
System.out.println("Parallel execution merged");
engine.setVariable("parallel_branches_active", false);
}
}
}
// BPMN Demo
public class BPMDemo {
public static void main(String[] args) {
System.out.println("=== BPMN Process Modeling Demo ===");
// Create process engine
BPMNProcessEngine engine = new BPMNProcessEngine();
// Create BPMN elements
StartEvent start = new StartEvent("start_bestellung", "Bestellung eingegangen");
UserTask pruefung = new UserTask("pruefe_bestellung", "Bestellung prüfen", "sachbearbeiter");
ExclusiveGateway gueltigCheck = new ExclusiveGateway("gueltig_pruefung", "Bestellung gültig?");
ServiceTask lagerPruefung = new ServiceTask("pruefe_lager", "Lagerbestand prüfen", "LagerService");
ParallelGateway parallelStart = new ParallelGateway("parallel_start", "Parallel starten");
UserTask rechnung = new UserTask("erstelle_rechnung", "Rechnung erstellen", "finanzabteilung");
ServiceTask versand = new ServiceTask("versende_ware", "Ware versenden", "VersandService");
ParallelGateway parallelEnd = new ParallelGateway("parallel_end", "Zusammenführen");
EndEvent endErfolgreich = new EndEvent("end_erfolgreich", "Bestellung abgeschlossen");
EndEvent endAbgelehnt = new EndEvent("end_abgelehnt", "Bestellung abgelehnt");
// Add elements to engine
engine.addElement(start);
engine.addElement(pruefung);
engine.addElement(gueltigCheck);
engine.addElement(lagerPruefung);
engine.addElement(parallelStart);
engine.addElement(rechnung);
engine.addElement(versand);
engine.addElement(parallelEnd);
engine.addElement(endErfolgreich);
engine.addElement(endAbgelehnt);
// Define sequence flows
engine.addSequenceFlow("start_bestellung", "pruefe_bestellung");
engine.addSequenceFlow("pruefe_bestellung", "gueltig_pruefung");
// Conditional flows for exclusive gateway
engine.addSequenceFlow("gueltig_pruefung", "pruefe_lager");
engine.addSequenceFlow("gueltig_pruefung", "end_abgelehnt");
engine.addSequenceFlow("pruefe_lager", "parallel_start");
engine.addSequenceFlow("parallel_start", "erstelle_rechnung");
engine.addSequenceFlow("parallel_start", "versende_ware");
engine.addSequenceFlow("erstelle_rechnung", "parallel_end");
engine.addSequenceFlow("versende_ware", "parallel_end");
engine.addSequenceFlow("parallel_end", "end_erfolgreich");
// Set process variables
engine.setVariable("bestellungGueltig", true);
// Execute process
engine.executeProcess("start_bestellung");
// Process statistics
System.out.println("\n=== Process Statistics ===");
System.out.println("Completed elements: " + engine.completedElements.size());
// Second run with invalid order
System.out.println("\n=== Second Run (invalid order) ===");
BPMNProcessEngine engine2 = new BPMNProcessEngine();
// Add elements again
Arrays.asList(start, pruefung, gueltigCheck, endAbgelehnt).forEach(engine2::addElement);
engine2.addSequenceFlow("start_bestellung", "pruefe_bestellung");
engine2.addSequenceFlow("pruefe_bestellung", "gueltig_pruefung");
engine2.addSequenceFlow("gueltig_pruefung", "end_abgelehnt");
engine2.setVariable("bestellungGueltig", false);
engine2.executeProcess("start_bestellung");
}
}
3. BPMN Data Objects and Artifacts
// BPMN Data Objects
class DataObject {
private String id;
private String name;
private Object value;
private String dataType;
public DataObject(String id, String name, String dataType) {
this.id = id;
this.name = name;
this.dataType = dataType;
}
// Getter and Setter
public String getId() { return id; }
public String getName() { return name; }
public Object getValue() { return value; }
public void setValue(Object value) { this.value = value; }
public String getDataType() { return dataType; }
@Override
public String toString() {
return "DataObject{" + name + "=" + value + " (" + dataType + ")}";
}
}
// BPMN Group
class BPMNGroup {
private String id;
private String name;
private List<String> elementIds;
private String categoryValue;
public BPMNGroup(String id, String name, String categoryValue) {
this.id = id;
this.name = name;
this.categoryValue = categoryValue;
this.elementIds = new ArrayList<>();
}
public void addElement(String elementId) {
elementIds.add(elementId);
}
// Getter
public String getId() { return id; }
public String getName() { return name; }
public List<String> getElementIds() { return new ArrayList<>(elementIds); }
public String getCategoryValue() { return categoryValue; }
}
// BPMN Text Annotation
class TextAnnotation {
private String id;
private String text;
private String format;
public TextAnnotation(String id, String text) {
this.id = id;
this.text = text;
this.format = "text/plain";
}
// Getter
public String getId() { return id; }
public String getText() { return text; }
public String getFormat() { return format; }
}
// Advanced BPMN Engine with Data Objects
class AdvancedBPMNEngine extends BPMNProcessEngine {
private Map<String, DataObject> dataObjects = new HashMap<>();
private Map<String, BPMNGroup> groups = new HashMap<>();
private Map<String, TextAnnotation> annotations = new HashMap<>();
public void addDataObject(DataObject dataObject) {
dataObjects.put(dataObject.getId(), dataObject);
}
public void addGroup(BPMNGroup group) {
groups.put(group.getId(), group);
}
public void addAnnotation(TextAnnotation annotation) {
annotations.put(annotation.getId(), annotation);
}
public DataObject getDataObject(String id) {
return dataObjects.get(id);
}
public void setDataObjectValue(String id, Object value) {
DataObject dataObject = dataObjects.get(id);
if (dataObject != null) {
dataObject.setValue(value);
}
}
public void printProcessInfo() {
System.out.println("\n=== Process Information ===");
System.out.println("\nData Objects:");
dataObjects.values().forEach(System.out::println);
System.out.println("\nGroups:");
groups.values().forEach(group -> {
System.out.println(group.getName() + " (" + group.getCategoryValue() + "): " +
group.getElementIds());
});
System.out.println("\nAnnotations:");
annotations.values().forEach(annotation ->
System.out.println(annotation.getText()));
}
}
// Demo with advanced BPMN features
public class AdvancedBPMDemo {
public static void main(String[] args) {
System.out.println("=== Advanced BPMN Demo ===");
AdvancedBPMNEngine engine = new AdvancedBPMNEngine();
// BPMN Elements
StartEvent start = new StartEvent("start_antrag", "Request received");
UserTask pruefung = new UserTask("pruefe_antrag", "Review request", "sachbearbeiter");
ServiceTask pruefungService = new ServiceTask("automatische_pruefung",
"Automatic Review",
"PruefService");
EndEvent endGenehmigt = new EndEvent("end_genehmigt", "Request approved");
EndEvent endAbgelehnt = new EndEvent("end_abgelehnt", "Request rejected");
// Add Elements
Arrays.asList(start, pruefung, pruefungService, endGenehmigt, endAbgelehnt)
.forEach(engine::addElement);
// Data Objects
DataObject antragData = new DataObject("antrag_daten", "Request Data", "Request");
DataObject pruefungsErgebnis = new DataObject("pruefung_ergebnis",
"Review Result",
"Boolean");
engine.addDataObject(antragData);
engine.addDataObject(pruefungsErgebnis);
// Group for Review Process
BPMNGroup pruefungsGruppe = new BPMNGroup("pruefungsgruppe",
"Review Process",
"Review");
pruefungsGruppe.addElement("pruefe_antrag");
pruefungsGruppe.addElement("automatische_pruefung");
engine.addGroup(pruefungsGruppe);
// Annotation
TextAnnotation hinweis = new TextAnnotation("hinweis",
"Important: All reviews must be documented");
engine.addAnnotation(hinweis);
// Sequence Flows
engine.addSequenceFlow("start_antrag", "pruefe_antrag");
engine.addSequenceFlow("pruefe_antrag", "automatische_pruefung");
engine.addSequenceFlow("automatische_pruefung", "end_genehmigt");
// Initialize Data Objects
engine.setDataObjectValue("antrag_daten", "Request #12345");
engine.setDataObjectValue("pruefung_ergebnis", true);
// Execute Process
engine.executeProcess("start_antrag");
// Print Process Information
engine.printProcessInfo();
}
}
BPMN Elements Overview
Events
| Type | Symbol | Description | Example |
|---|---|---|---|
| Start Event | Circle (thin) | Process start | Request received |
| End Event | Circle (thick) | Process end | Request completed |
| Intermediate Event | Circle (double) | Intermediate event | Timer triggered |
| Boundary Event | Circle (attached) | Error event | Task timeout |
| Message Event | Envelope | Message | Message received |
| Timer Event | Clock | Time-based | Waiting time expired |
Tasks
| Type | Symbol | Description | Example |
|---|---|---|---|
| User Task | Rectangle with person | Manual task | Fill out form |
| Service Task | Rectangle with gear | Automated task | Save to database |
| Script Task | Rectangle with script | Script execution | Perform calculation |
| Manual Task | Rectangle with hand | Manual without IT | Package item |
| Receive Task | Rectangle with envelope | Wait for message | Wait for confirmation |
| Send Task | Rectangle with envelope | Send message | Send email |
Gateways (Branching)
| Type | Symbol | Description | Example |
|---|---|---|---|
| Exclusive Gateway | Diamond (X) | Exclusive branching | Yes/No decision |
| Parallel Gateway | Diamond (+) | Parallel execution | Check simultaneously |
| Inclusive Gateway | Diamond (O) | Inclusive branching | Multiple conditions |
| Complex Gateway | Diamond (*) | Complex logic | Multiple conditions |
Swimlanes
| Element | Description | Usage |
|---|---|---|
| Pool | Process container | Entire process of an organization |
| Lane | Area of responsibility | Department or role |
| Participant | External partner | Customer, supplier |
BPMN XML Structure
Basic Structure
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="prozess_id" name="Prozessname">
<!-- BPMN-Elemente -->
<startEvent id="start" name="Start"/>
<sequenceFlow sourceRef="start" targetRef="task1"/>
<userTask id="task1" name="Aufgabe"/>
<endEvent id="end" name="Ende"/>
</process>
</definitions>
Advanced Structure
<definitions>
<process id="prozess">
<!-- Pools and Lanes -->
<participant id="participant1" name="Organisation"/>
<lane id="lane1" name="Abteilung">
<flowNodeRef>task1</flowNodeRef>
</lane>
<!-- Data objects -->
<dataObject id="data1" name="Daten" itemSubjectRef="itemDef1"/>
<!-- Artifacts -->
<textAnnotation id="annotation1">
<text>Hinweis</text>
</textAnnotation>
</process>
</definitions>
BPMN Best Practices
Process Design
- Clarity: Keep processes simple and understandable
- Consistency: Use uniform notation and naming
- Completeness: Model all relevant paths
- Validation: Regularly review models
Naming Conventions
- Element IDs: Technical identifiers (no spaces)
- Element Names: Human-readable descriptions
- Process Variables: CamelCase with technical focus
- Data Objects: Descriptive names with data type
Performance Optimization
- Parallelization: Leverage opportunities for parallel execution
- Automation: Minimize manual tasks
- Simplification: Avoid unnecessary gateways
- Reusability: Use sub-processes for recurring workflows
Advantages and Disadvantages
Advantages of BPMN
- Standardization: Uniform notation worldwide
- Tool Support: Many BPMN tools available
- Automation: Direct implementation in BPM systems
- Communication: Common understanding among all stakeholders
- Analysis: Systematic process improvement
Disadvantages
- Complexity: Learning curve for complex processes
- Overhead: Detailed modeling can be time-consuming
- Interpretation: Different tools may vary slightly
- Maintenance: Models must be kept up to date
Common Exam Questions
-
What is the difference between a pool and a lane? A pool is the entire process container, while a lane is an area of responsibility within a pool.
-
Explain the different gateway types! Exclusive (exclusive), Parallel (simultaneous), Inclusive (multiple conditions), Complex (complex logic).
-
When do you use User Task vs Service Task? User Task for manual tasks performed by users, Service Task for automated system tasks.
-
What is the purpose of BPMN data objects? Representation of information that flows through and is processed in the process.
Key Sources
- https://www.bpmn.org/
- https://www.omg.org/spec/BPMN/2.0/
- https://de.wikipedia.org/wiki/Business_Process_Model_and_Notation