Übungsaufgaben zum UML-Sequenzdiagramm

https://bildung.social/@oerinformatik/

https://oer-informatik.de/uml-sequenzdiagramm-uebungsaufgaben

UML, Sequenzdiagramm, kombinierte Fragmente, Beobachter-Muster, Stellvertreter-Muster, REST, Pseudocode, Übungsaufgaben, Prüfungsvorbereitung

tl/dr; (Bearbeitungszeit insgesamt 132 min, mehrere Aufgaben): Vier Übungsaufgaben zum UML-Sequenzdiagramm. Du leitest ein Diagramm aus einem Server-Protokoll ab, liest daraus Wartezeiten ab und entscheidest zwischen synchronen und asynchronen Nachrichten. Danach modellierst Du Objekterzeugung, Selbstaufrufe, verschachtelte Fragmente und Objektzerstörung, bewertest einen REST-Ablauf mit Cache, leitest ein Beobachter-Muster aus Java-Code ab, korrigierst einen fehlerhaften Entwurf, stellst einen Ablauf zwischen Menschen dar und setzt Pseudocode, ein Stellvertreter-Muster und einen Diagrammentwurf in Code bzw. Diagramme um. Alle Lösungen sind ausgeblendet und mit Punkteverteilung versehen [AI-Assisted]. (Zuletzt geändert am 29.10.2026)

Dieser Artikel ist Teil einer Artikelreihe über UML-Sequenzdiagramme: Einstieg in das Sequenzdiagramm (Übungsaufgaben) / Sequenzdiagramme mit PlantUML erstellen / Kurzübungen: TCP-Handshake, 2FA, CRAM-MD5, MQTT-Nachrichtenfluss, Webpage per MVP-Pattern, Zugriff erlauben mit OAuth2, Authentifizieren mit Passkey.

Diese Übungsaufgaben gehören zum Artikel UML-Sequenzdiagramme. Sie setzen die Grundlagen des UML-Klassendiagramms voraus und greifen die Entwurfsmuster Beobachter und Stellvertreter auf, die Du im Artikel zum Sequenzdiagramm kurz kennenlernst. Weitere, kleinere Übungen findest Du unter Übungsaufgaben zu UML-Sequenzdiagrammen.

Wortwolke mit den wichtigsten Begriffen der Übungsaufgaben: Sequenzdiagramm, Lebenslinie, synchrone und asynchrone Nachricht, Antwort, Ausführungsbalken, kombinierte Fragmente, Beobachter- und Stellvertreter-Muster (mit KI erstellt)

Hinweise zur Bearbeitung: Als FIA, FIDP oder FIDV musst Du zur Teil-2-Prüfung Aufgaben auf Kernkompetenz-Ebene lösen können, das ist Aufgabe 2.1. Von FIA wird zusätzlich erwartet, dass ihnen Aufgaben auf Profilkompetenz-Ebene (Aufgabe 3.1, Aufgabe 3.2 und Aufgabe 3.3) keine Probleme bereiten. Zeichne Deine Diagramme auf Papier oder mit einem Werkzeug Deiner Wahl, bevor Du die Beispiellösung aufklappst. Eine saubere Handskizze genügt. Achte auf die Pfeilarten (synchron: durchgezogen mit gefüllter Spitze, Antwort: gestrichelt, asynchron: durchgezogen mit offener Spitze), auf die Beschriftung jedes Pfeils und auf die Ausführungsbalken. Du darfst eine Notationsübersicht nutzen:

Notationsübersicht zum UML-Sequenzdiagramm: synchrone Nachricht, Antwort, asynchrone Nachricht, Selbstaufruf, Erzeugung und kombiniertes Fragment alt (mit KI erstellt)

Weitere Interaktionsoperatoren für kombinierte Fragmente: alt, opt, loop, break, par, neg, seq, strict, critical, ref (Verweis). Eine Objektzerstörung wird mit einem X am Ende der Lebenslinie notiert.

Andere fachlich richtige Lösungen sind ebenfalls richtig, z. B. abweichende Variablennamen für Rückgabewerte. Pseudocode darf in jeder üblichen Schreibweise notiert werden.

Du möchtest eigene Aufgaben zum Üben von einem KI-Sprachmodell generieren lassen?

Kopiere den Text in ein KI-Sprachmodell Deiner Wahl und passe Kompetenzstufe, Anzahl, Bearbeitungszeit und Szenario bei Bedarf an. Wie die Aufgaben aufgebaut sind, beschreibt der Artikel Wie sind die Aufgaben aufgebaut?. Prüfe die Ergebnisse mit dem Lehrartikel: KI-Sprachmodelle machen Fehler.

Erstelle neue Übungsaufgaben zum Thema „UML-Sequenzdiagramm“.

Bauplan: Halte Dich an Aufbau, Kompetenzstufen, Operatoren,
Anforderungsbereiche, Punkte und Zeitschätzung, die im Artikel
https://oer-informatik.de/aufgaben-aufbau beschrieben sind.

Fachliche Grundlage:
- https://oer-informatik.de/uml-sequenzdiagramm
- https://oer-informatik.de/uml-klassendiagramm
- https://oer-informatik.de/uml-sequenzdiagramm-plantuml
- Stilbeispiel: https://oer-informatik.de/uml-sequenzdiagramm-uebungsaufgaben

Die Aufgaben sollen Inhalte zu diesen Schlagwörtern abdecken:
- UML
- Sequenzdiagramm
- kombinierte Fragmente
- Beobachter-Muster
- Stellvertreter-Muster
- REST
- Pseudocode

Kompetenzstufe: Profilkompetenz (alternativ: Basiskompetenz, Kernkompetenz, Expertise)
Anzahl: 1 Aufgabe mit Teilaufgaben
Bearbeitungszeit in Minuten ca.: <5 bis 30 min>
Szenario: eines der Szenarien aus dem Bauplan

Vorgehen:
1. Lies zuerst die verlinkten Artikel. Kannst Du keine Webseiten
   abrufen, sag mir das, statt zu raten.
2. Steht bei einer Angabe noch ein Platzhalter in <…>, frag mich
   zuerst danach. Richte Punkte und Zahl der Teilaufgaben nach der
   Bearbeitungszeit (ca. 0,9 min je Punkt).
3. Gib je Aufgabe Titel mit Kompetenzstufe, Ausgangssituation und
   Teilaufgaben mit Operator und Punktzahl aus, dazu die geschätzte
   Bearbeitungszeit.
4. Gib die Beispiellösungen mit Punkteverteilung erst aus, wenn ich
   danach frage.

Aufgabe 2.1: Einlass in eine Werkstatt-Session beim Barcamp (Kernkompetenz)

(ca. 26 min Bearbeitungszeit)

Beim Barcamp „Lernen.Digital.Leben 2027“ am Ratz und Rübe Berufskolleg (RRB) haben einige Werkstatt-Sessions nur wenige Plätze, etwa Mia Schröders „Escape-Room mit Mikrocontrollern“ (Session S14, Raum B.104, 12 Plätze). An der Tür solcher Räume hängt ein Raumscanner, der den QR-Code auf dem Badge liest und die Teilnahme bei der SessionAPI einträgt. Daneben zeigt ein E-Ink-Türschild die freien Plätze an. Jeder Scanner hat beim Aufbau einen eigenen Geräteschlüssel erhalten, den er bei jeder Anfrage im Header mitschickt. Eine Anmeldung per Benutzername und Passwort gibt es am Scanner nicht.

Dimitrios Papadopoulos hat für die Dokumentation einen gelungenen Einlass aus dem Protokoll der SessionAPI herauskopiert. Alle Zeitstempel stammen von der Uhr der API, Laufzeiten im Schul-WLAN vernachlässigst Du.

10:58:31.402  von scanner-B104   PUT /api/sessions/S14/teilnahmen/P-0273
                                 Authorization: Bearer gk-b104-…
10:58:31.405  intern             geraetPruefen(schluessel) -> gueltig
10:58:31.409  an db              SELECT plaetze, belegt FROM session WHERE id = 'S14'
10:58:31.425  von db             plaetze = 12, belegt = 11
10:58:31.428  an db              INSERT INTO teilnahme (session_id, person_id) VALUES ('S14', 'P-0273')
10:58:31.447  von db             1 Zeile
10:58:31.449  an schild-B104     zeigeFreiePlaetze(0)   (wartet nicht auf Rückmeldung)
10:58:31.451  an scanner-B104    201 Created

Was das Protokoll nicht zeigt: Ist die Session schon voll, trägt die API nichts ein, schickt dem Türschild nichts und antwortet mit 409 Conflict. Der Scanner leuchtet nach 201 grün (leuchteGruen()), nach 409 rot (leuchteRot()).

a) Leite aus dem Protokoll und der Ergänzung ein UML-Sequenzdiagramm ab. Verwende die Lebenslinien scanner :Raumscanner, :SessionAPI, :Datenbank und schild :Tuerschild. Kläre vorher für jede Zeile: Wer schickt hier wem etwas, und wartet der Absender auf ein Ergebnis? Welche Zeilen beschreiben etwas, das ein Teilnehmer nur selbst tut? (15 Punkte)

Sequenzdiagramm des Einlasses: PUT mit Geräteschlüssel im Header, Selbstaufruf zur Geräteprüfung, Datenbankabfrage, alt-Fragment mit INSERT, asynchroner Meldung an das Türschild und Antwort 201 bzw. 409 (mit KI erstellt)

Bewertung:

  • PUT /api/sessions/S14/teilnahmen/P-0273 als synchrone Nachricht, der Geräteschlüssel als Notiz Authorization: Bearer … am Pfeil statt als Parameter (2 Punkte),
  • geraetPruefen(schluessel) als Selbstaufruf mit versetztem Balken und Antwort gueltig (2 Punkte),
  • SELECT … an die Datenbank mit Antwort plaetze = 12, belegt = 11 (2 Punkte),
  • alt-Fragment mit [belegt < plaetze] und [else], die Abfrage liegt davor (2 Punkte),
  • INSERT INTO teilnahme … mit Antwort im ersten Operanden (1 Punkt),
  • zeigeFreiePlaetze(0) asynchron (offene Pfeilspitze, keine Antwort) und nur im ersten Operanden (2 Punkte),
  • Response 201 Created im ersten, Response 409 Conflict im zweiten Operanden, jeweils gestrichelt zum Scanner (2 Punkte),
  • leuchteGruen() bzw. leuchteRot() als Selbstaufruf des Scanners im passenden Operanden (je 1 Punkt).

Der Balken des Scanners bleibt vom PUT bis zur Antwort bestehen, weil er wartet. Die Zeilen „intern“ und das Leuchten sind keine Nachrichten an andere Teilnehmer, sondern Selbstaufrufe. Die Werte 12 und 11 darfst Du auch weglassen und allgemein plaetze, belegt schreiben.

b) Werte die Zeitstempel aus.

ba) Bestimme, wie lange der Raumscanner auf seine Antwort wartet und wie viel dieser Zeit die SessionAPI ihrerseits auf die Datenbank wartet. Erkläre mit dem Diagramm aus a), warum die Wartezeit der Datenbank in der Wartezeit des Scanners enthalten ist. (3 Punkte)

bb) Das Türschild braucht etwa 800 ms, bis die E-Ink-Anzeige umgeblättert ist. Emre Aksoy schlägt vor, zeigeFreiePlaetze synchron aufzurufen, „damit die API sicher weiß, dass das Schild stimmt“. Bewerte den Vorschlag. Berechne dazu, wie lange der Scanner dann warten würde, und schätze die Folgen ab, wenn zu Beginn der Session zwölf Personen nacheinander scannen. (4 Punkte)

ba) Der Scanner wartet von 31.402 bis 31.451, also 49 ms (1 Punkt). Die API wartet zweimal auf die Datenbank: 31.409 bis 31.425 = 16 ms und 31.428 bis 31.447 = 19 ms, zusammen 35 ms (1 Punkt). Beide Datenbankaufrufe sind synchron und liegen innerhalb des Ausführungsbalkens der API, der wiederum innerhalb des wartenden Balkens des Scanners liegt. Jede Millisekunde, die die API wartet, wartet der Scanner mit (1 Punkt).

bb) Synchron müsste die API die 800 ms des Türschilds abwarten, bevor sie mit 201 antwortet. Die Antwort käme etwa um 32.251 an, der Scanner wartet dann rund 849 ms statt 49 ms (1 Punkt). Zwölf Personen hintereinander warten zusammen etwa 12 · 0,849 s ≈ 10,2 s nur auf das System statt etwa 0,6 s; an der Tür entsteht eine Schlange, obwohl für den Einlass nur die Datenbank zählt (1 Punkt). Ist das Schild per Funk gerade nicht erreichbar (z. B. leerer Akku), hängt der Scanner bis zu einer Zeitüberschreitung, und niemand kommt mehr hinein (1 Punkt). Der Vorschlag ist deshalb abzulehnen: Die Anzeige ist eine Nebensache, der Einlass darf nicht von ihr abhängen. Ob das Schild stimmt, lässt sich anders sichern, z. B. indem das Schild nach dem Umblättern selbst eine asynchrone Meldung schickt oder die API den aktuellen Stand regelmäßig erneut sendet (1 Punkt).

c) Für das nächste Barcamp sind drei Erweiterungen geplant. Entscheide jeweils, ob die neue Nachricht synchron oder asynchron modelliert werden sollte, und begründe Deine Entscheidung. (6 Punkte)

  1. Vor dem Eintragen fragt die SessionAPI beim Ticketdienst nach, ob das Badge zu einem gültigen Tagesticket gehört.
  2. Nach jedem Einlass erhöht ein Statistikdienst den Zähler für die Abschlussfolie im Plenum.
  3. Antwortet die API mit 409, bekommt die Session-Leitung eine Push-Nachricht aufs Handy, damit sie bei Bedarf Stühle holen lässt.

Je Fall 1 Punkt für die Entscheidung und 1 Punkt für die Begründung:

  1. Synchron: Das Ergebnis entscheidet, ob die API überhaupt einträgt und ob der Scanner grün oder rot leuchtet. Ohne Antwort kann die API nicht weitermachen.
  2. Asynchron: Die API braucht vom Statistikdienst kein Ergebnis. Fällt der Dienst aus oder ist er langsam, soll der Einlass trotzdem sofort funktionieren.
  3. Asynchron: Ob und wann die Nachricht auf dem Handy ankommt, ändert nichts an der Antwort an den Scanner. Die Zustellung über einen Push-Dienst kann Sekunden dauern oder scheitern, wenn das Handy offline ist.

Andere Entscheidungen sind richtig, wenn die Begründung trägt, z. B. Fall 2 synchron, wenn der Zähler ausdrücklich vor der Antwort an den Scanner stimmen muss.

Aufgabe 3.1: Teilnahme an einer Freizeitaktivität (Profilkompetenz)

(ca. 35 min Bearbeitungszeit)

Du bist Auszubildende*r im Entwicklungsteam der Let’s Meet GmbH in Bielefeld. Die Kennenlern-App „Let’s Meet“ bringt Menschen für gemeinsame Freizeitaktivitäten zusammen. Für das neue Backend soll die Anmeldung zu einer Aktivität mit Warteliste umgesetzt werden. Bevor Jonas Weber mit der Programmierung beginnt, bittet Euer Ausbilder Yusuf Demir Dich, den Ablauf als Sequenzdiagramm zu dokumentieren. Er gibt Dir einen Auszug aus dem Klassenmodell:

TeilnahmeController
  + anmelden(aktivitaetId: Integer, benutzerId: Integer): String
  + absagen(aktivitaetId: Integer): String
  - istZugelassen(b: Benutzer, akt: Aktivitaet): Boolean

Verwaltung
  + findeBenutzer(benutzerId: Integer): Benutzer
  + findeAktivitaet(aktivitaetId: Integer): Aktivitaet
  + loescheAktivitaet(akt: Aktivitaet): void

Aktivitaet
  + istAltersgerecht(b: Benutzer): Boolean
  + freiePlaetze(): Integer
  + fuegeHinzu(t: Teilnahme): String
  + getTeilnahmen(): Teilnahme[]
  + loeschen(): void

Teilnahme
  + Teilnahme(b: Benutzer)
  + setStatus(status: String): void
  + getBenutzer(): Benutzer

Benutzer
  + getPushToken(): String

PushDienst
  + sendePush(b: Benutzer, text: String): void

MailDienst
  + sendeMail(b: Benutzer, text: String): void

Yusuf beschreibt die Anmeldung so:

  • Die App ruft beim TeilnahmeController die Methode anmelden(aktivitaetId, benutzerId) auf.
  • Der Controller lässt sich von der Verwaltung zuerst den Benutzer b und dann die Aktivität akt geben.
  • Mit seiner eigenen Methode istZugelassen(b, akt) prüft der Controller, ob b teilnehmen darf. Dazu fragt istZugelassen die Aktivität mit istAltersgerecht(b), ob b das Mindestalter der Aktivität (16 oder 18 Jahre) erfüllt. Weitere Prüfungen, z. B. auf eine Sperre, erledigt istZugelassen ohne weitere Aufrufe.
  • Ist b nicht zugelassen, erhält die App den Text „nicht zugelassen“.
  • Andernfalls erzeugt der Controller für b ein neues Objekt t der Klasse Teilnahme und übergibt es mit fuegeHinzu(t) an die Aktivität. Die Aktivität ermittelt mit ihrer eigenen Methode freiePlaetze() die Zahl der freien Plätze. Ist mindestens ein Platz frei, setzt sie den Status von t auf „angemeldet“, sonst auf „warteliste“. fuegeHinzu gibt den gesetzten Status zurück.
  • Ist der Status „angemeldet“, schickt der Controller über den PushDienst die Nachricht „Du bist dabei!“ an b, sonst „Du stehst auf der Warteliste.“. Der Controller wartet nicht, bis die Nachricht zugestellt ist.
  • Zum Schluss erhält die App den Status.

a) Erstelle für die Anmeldung ein UML-Sequenzdiagramm mit dem Interaktionsrahmen „sd Teilnahme anmelden“. Verwende die Lebenslinien :App, :TeilnahmeController, :Verwaltung, akt :Aktivitaet, t :Teilnahme und :PushDienst. Zeichne alle Nachrichten mit Beschriftung, alle Antworten mit Rückgabewerten und alle Ausführungsbalken ein. (24 Punkte)

Beispiellösung: Sequenzdiagramm „Teilnahme anmelden“ mit Selbstaufrufen, Erzeugung der Teilnahme, verschachtelten alt-Fragmenten und asynchronen Push-Nachrichten (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 2 Punkte: Erzeugung von t :Teilnahme mit gestricheltem Pfeil und offener Spitze, Kopf der Lebenslinie erst auf Höhe der Erzeugung (new(b)).
  • 11 Punkte: je 1 Punkt für jede richtig gerichtete und beschriftete Nachricht: anmelden(…), findeBenutzer(…), findeAktivitaet(…), istZugelassen(b, akt) als Selbstaufruf, istAltersgerecht(b), fuegeHinzu(t), freiePlaetze() als Selbstaufruf der Aktivität, setStatus("angemeldet"), setStatus("warteliste"), zweimal sendePush(…).
  • 5 Punkte: je 0,5 Punkte für jede Antwort mit Rückgabewert (b, akt, alterOk, zugelassen, plaetze, zweimal setStatus, status, „nicht zugelassen“, status an die App).
  • 3 Punkte: je 1 Punkt für die drei alt-Fragmente mit Bedingungen in eckigen Klammern ([zugelassen == false]/[else], [plaetze > 0]/[else], [status == "angemeldet"]/[else]); das Fragment zu den freien Plätzen liegt im Ausführungsbalken der Aktivität, das Fragment zu den Push-Nachrichten im zweiten Zweig des äußeren Fragments.
  • 2 Punkte: Ausführungsbalken, insbesondere die verschachtelten Balken der Selbstaufrufe (der Aufruf von istAltersgerecht startet im inneren Balken von istZugelassen).
  • 1 Punkt: sendePush als asynchrone Nachricht (offene Pfeilspitze, keine Antwort).

Hinweise: Die Antwort auf istZugelassen darf auch direkt im Bedingungstext ausgewertet werden ([nicht zugelassen]). Ein opt-Fragment statt des äußeren alt ist falsch, weil beide Fälle unterschiedliche Abläufe haben.

b) Begründe, warum sendePush als asynchrone Nachricht, findeBenutzer dagegen als synchrone Nachricht modelliert wird. (2 Punkte)

  • findeBenutzer: Der Controller braucht das Ergebnis (das Benutzerobjekt b), um weiterzuarbeiten. Er muss also warten, bis die Methode beendet ist → synchron (1 Punkt).
  • sendePush: Der Controller braucht keine Antwort; die Zustellung an das Smartphone kann dauern oder scheitern (Gerät aus), und die Anmeldung soll trotzdem sofort abgeschlossen werden. Der Sender arbeitet also ohne zu warten weiter → asynchron (1 Punkt).

c) Organisator*innen können eine Aktivität absagen. Yusuf beschreibt den Ablauf so:

  • Die App ruft beim Controller absagen(aktivitaetId) auf. Der Controller lässt sich von der Verwaltung die Aktivität akt geben und fragt sie mit getTeilnahmen() nach allen Teilnahmen.
  • Für jede Teilnahme t fragt der Controller mit getBenutzer() den Benutzer b ab und lässt sich mit getPushToken() dessen Push-Token geben. Ist der Token ein leerer String (App-Benachrichtigungen ausgeschaltet), schickt der Controller über den MailDienst die Nachricht „Abgesagt“, sonst über den PushDienst. In beiden Fällen wartet er nicht auf die Zustellung.
  • Danach ruft der Controller loescheAktivitaet(akt) bei der Verwaltung auf. Diese ruft loeschen() an der Aktivität auf, wodurch das Objekt akt zerstört wird. (Dass dabei auch die Teilnahmen gelöscht werden, musst Du nicht darstellen.)
  • Die App erhält den Text „abgesagt“.

Zeichne das Sequenzdiagramm „sd Aktivitaet absagen“. Ergänze dazu die Lebenslinien b :Benutzer und :MailDienst. (12 Punkte)

Beispiellösung: Sequenzdiagramm „Aktivitaet absagen“ mit Schleife über alle Teilnahmen, Alternative E-Mail oder Push und Zerstörung der Aktivität (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 4,5 Punkte: je 0,5 Punkte für die neun beschrifteten Nachrichten (absagen, findeAktivitaet, getTeilnahmen, getBenutzer, getPushToken, sendeMail, sendePush, loescheAktivitaet, loeschen).
  • 3,5 Punkte: je 0,5 Punkte für die sieben Antworten mit Rückgabewerten (akt, teilnahmen, b, token, Antwort auf loeschen(), Antwort auf loescheAktivitaet(akt), „abgesagt“).
  • 1,5 Punkte: loop-Fragment mit Bedingung (z. B. [für jede Teilnahme t in teilnahmen]), das genau die Nachrichten je Teilnahme umschließt.
  • 1,5 Punkte: alt-Fragment innerhalb der Schleife mit den Bedingungen [token == ""] und [else]; sendeMail und sendePush asynchron.
  • 1 Punkt: Zerstörung von akt mit einem X am Ende der Lebenslinie direkt nach loeschen(); danach keine Nachrichten mehr an akt.

Hinweis: Die Lebenslinien t :Teilnahme und b :Benutzer stehen in der Schleife jeweils für das gerade bearbeitete Objekt. Wer getPushToken() weglässt und den Token als Bedingung [b hat keinen Push-Token] notiert, verliert 1 Punkt (Nachricht und Antwort).

Aufgabe 3.2: Schließanlagen und Lagerbestand im Fahrradshop (Profilkompetenz)

(ca. 36 min Bearbeitungszeit)

Du bist Auszubildende*r in der IT der CSB-Rad GmbH in Bielefeld. Im Onlineshop können Kund*innen über den Konfigurator weitere Schlösser zu einer bestehenden gleichschließenden Schließanlage nachbestellen. Die Daten der Schließanlagen stellt die Lipper SchließTec KG über eine REST-API bereit. Sie erlaubt dem Shop nur eine begrenzte Zahl von Abrufen je Stunde; wer mehr anfragt, erhält den Statuscode 429 (Too Many Requests). Das Shop-Backend legt abgerufene Schließanlagen deshalb in einem eigenen Zwischenspeicher-Dienst ab, dem AnlagenCache. Der bisherige Ablauf sieht so aus:

Bisheriger Ablauf: Das ShopBackend fragt zuerst den AnlagenCache; nur wenn kein Eintrag vorhanden ist, ruft es die Schließanlage bei der SchließTec-API ab und legt sie im Cache ab (mit KI erstellt)

Michael Hartmann vom Zweckverband Radwege OWL beschwert sich: Seine Schließanlage wurde vor drei Tagen um zwei Schlüssel erweitert, der Konfigurator zeigt aber immer noch den alten Stand. Cem Sarıkaya, Geschäftsführer Technik und IT, legt deshalb Regeln für die fünf möglichen Fälle fest:

Regeln für den Abruf einer Schließanlage
Fall Eintrag im Cache Antwort der SchließTec-API Reaktion des Backends gegenüber dem Konfigurator
1 vorhanden, jünger als 24 Stunden API wird nicht gefragt 200 mit der Anlage aus dem Cache
2 fehlt oder älter als 24 Stunden 200 mit der Anlage Eintrag im Cache neu anlegen bzw. ersetzen, 200 mit der neuen Anlage
3 fehlt oder älter als 24 Stunden 404 Eintrag aus dem Cache entfernen, 404
4 älter als 24 Stunden 429 200 mit der alten Anlage und dem Hinweis „veraltet“
5 fehlt 429 503 (Service Unavailable)

a) Prüfe für jeden der fünf Fälle, ob der bisherige Ablauf ihn richtig, nur teilweise oder gar nicht abbildet. Erkläre damit auch die Beschwerde von Herrn Hartmann. (5 Punkte)

  • Fall 1: richtig abgebildet – liegt ein Eintrag vor, antwortet das Backend aus dem Cache (1 Punkt).
  • Fall 2: nur teilweise – ein fehlender Eintrag führt zum Abruf bei der API. Ein veralteter Eintrag ist aber auch != null und landet im ersten Operanden. Das Backend liefert ihn ohne Altersprüfung aus. Genau das passiert Herrn Hartmann: Der Eintrag ist drei Tage alt, die Erweiterung erreicht den Konfigurator nie (2 Punkte).
  • Fälle 3 bis 5: gar nicht abgebildet – der bisherige Ablauf geht davon aus, dass die API immer mit 200 antwortet. Bei 404 oder 429 ist nicht festgelegt, was das Backend tut (je Fall 0,5 Punkte, zusammen 1,5 Punkte; 0,5 Punkte für die Begründung).

b) Zeichne das Sequenzdiagramm neu, sodass es alle fünf Fälle abbildet. Behalte die Lebenslinien bei. Der AnlagenCache bietet die Methoden hole(code) (liefert den Eintrag samt Alter oder null), lege(code, anlage) und entferne(code). (14 Punkte)

Beispiellösung: Abruf einer Schließanlage mit Altersprüfung des Cache-Eintrags, drei Operanden für die API-Antworten 200, 404 und 429 und einer inneren Alternative für den Rückgriff auf den veralteten Eintrag (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 1 Punkt: hole(code) an den AnlagenCache mit Antwort eintrag.
  • 2 Punkte: äußeres alt-Fragment, dessen erste Bedingung auch das Alter prüft ([eintrag != null und eintrag.alter < 24 h]), und [else].
  • 1 Punkt: Antwort 200 aus dem Cache im ersten Operanden.
  • 1 Punkt: GET-Anfrage an die SchließTec-API im zweiten Operanden.
  • 2 Punkte: inneres alt-Fragment mit drei Operanden für die Antworten 200, 404 und 429 (zwei verschachtelte Fragmente sind ebenso richtig).
  • 1,5 Punkte: je 0,5 Punkte für die drei Antworten der API.
  • 1 Punkt: lege(code, anlage) mit Antwort im Operanden für 200.
  • 1 Punkt: entferne(code) mit Antwort im Operanden für 404.
  • 1,5 Punkte: innerstes alt-Fragment mit [eintrag != null]/[else] im Operanden für 429, darin 200 mit der veralteten Anlage bzw. 503.
  • 1 Punkt: Antworten 200 und 404 an den Konfigurator in den passenden Operanden.
  • 1 Punkt: Ausführungsbalken (Backend während der ganzen Anfrage aktiv, Cache und API nur während ihrer Bearbeitung).

Hinweise: HTTP-Anfragen werden wie synchrone Aufrufe notiert, weil der Client auf die Antwort wartet. Fall 4 entspricht der Idee von stale-if-error aus RFC 5861: Lieber einen leicht veralteten Stand zeigen als gar keinen. Wer die Altersprüfung als eigene Nachricht modelliert (z. B. eintrag.istFrisch()), erhält die vollen Punkte.

Für den Einkauf entstehen zwei Programme, die auf knappe Artikel reagieren: ein Dashboard, das eine Warnung anzeigt, und eine automatische Nachbestellung beim Großhandel. Bastian Ludwig, zuständig für Werkstatt und Einkauf, wollte sie unabhängig vom Lager entwickeln lassen. Beide sind deshalb über das Beobachter-Muster an den Lagerbestand gekoppelt. Der Code ist schon geschrieben (Java, Ausschnitt):

public interface LagerBeobachter {
    void artikelKnapp(String artikelNr);
}

public class Lagerbestand {
    private final List<LagerBeobachter> beobachter = new ArrayList<>();
    private final Map<String, Integer> bestand = new HashMap<>();
    private final Map<String, Integer> mindestbestand = new HashMap<>();

    public void anmelden(LagerBeobachter b) {
        beobachter.add(b);
    }

    public int getBestand(String artikelNr) {
        return bestand.getOrDefault(artikelNr, 0);
    }

    public void entnehmen(String artikelNr, int menge) {
        int neu = getBestand(artikelNr) - menge;
        bestand.put(artikelNr, neu);
        if (neu < mindestbestand.getOrDefault(artikelNr, 0)) {
            for (LagerBeobachter b : beobachter) {
                b.artikelKnapp(artikelNr);
            }
        }
    }
}

public class EinkaufsDashboard implements LagerBeobachter {
    private final Lagerbestand lager;
    // Konstruktor ausgelassen

    @Override
    public void artikelKnapp(String artikelNr) {
        int rest = lager.getBestand(artikelNr);
        zeigeWarnung(artikelNr, rest);
    }

    private void zeigeWarnung(String artikelNr, int rest) { /* ... */ }
}

public class Nachbestellung implements LagerBeobachter {
    private final Grosshandel grosshandel;   // String bestelle(String artikelNr, int menge)
    // Konstruktor ausgelassen

    @Override
    public void artikelKnapp(String artikelNr) {
        grosshandel.bestelle(artikelNr, 20);
    }
}

Beim Start der Anwendung wurden die Objekte dash :EinkaufsDashboard und danach nb :Nachbestellung bei lager :Lagerbestand angemeldet. Im Lager liegen 48 Lichtsets (LIC-SET-01), der Mindestbestand beträgt 20 Stück. Für einen Werkstattauftrag bucht das :Lagerterminal die Entnahme entnehmen("LIC-SET-01", 30).

c) Zeichne das Sequenzdiagramm, das beim Ausführen dieser Entnahme entsteht. Zeige beide Beobachter mit ihren eigenen Folgeaufrufen und trage, wo möglich, die konkreten Werte ein. (10 Punkte)

Beispiellösung: Entnahme am Lagerterminal mit Selbstaufruf getBestand, opt-Fragment und Benachrichtigung von Dashboard und Nachbestellung in Anmeldereihenfolge (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 1 Punkt: entnehmen("LIC-SET-01", 30) vom Lagerterminal mit Antwort am Ende.
  • 1 Punkt: Selbstaufruf getBestand("LIC-SET-01") mit Rückgabe 48.
  • 1,5 Punkte: opt-Fragment mit Bedingung ([neu < mindestbestand] oder [18 < 20]), das die gesamte Benachrichtigung umschließt.
  • 2 Punkte: artikelKnapp("LIC-SET-01") erst an dash, dann an nb (Anmeldereihenfolge), jeweils mit Antwort, bevor der nächste Beobachter aufgerufen wird.
  • 1 Punkt: Rückruf getBestand("LIC-SET-01") von dash an lager mit Rückgabe 18; dafür ein zweiter, verschachtelter Balken auf lager.
  • 1 Punkt: zeigeWarnung("LIC-SET-01", 18) als Selbstaufruf von dash.
  • 1 Punkt: bestelle("LIC-SET-01", 20) von nb an den :Grosshandel mit Rückgabe auftragNr.
  • 1,5 Punkte: Ausführungsbalken (lager während der ganzen Entnahme aktiv, Beobachter nur während artikelKnapp).

Ein loop-Fragment ist hier nicht nötig, weil das Diagramm einen konkreten Durchlauf mit zwei bekannten Beobachtern zeigt (siehe Teilaufgabe d). Wer die Schleife zusätzlich als loop um beide Aufrufe zeichnet, erhält die vollen Punkte.

d) Eine Kollegin zeichnet die Benachrichtigung anders: ein loop-Fragment [für jeden b in beobachter] mit einer einzigen Lebenslinie b :LagerBeobachter, an die artikelKnapp(artikelNr) geht. Vergleiche ihre Darstellung mit Deiner aus c). Erläutere, was jede Darstellung zeigt und was nicht, und für welchen Zweck welche besser geeignet ist. (3 Punkte)

  • Konkreter Ablauf wie in c): Er zeigt, was bei genau dieser Anmeldung wirklich passiert: Reihenfolge der Beobachter, der Rückruf getBestand des Dashboards, die Bestellung beim Großhandel, konkrete Werte. Er gilt aber nur für diese Konstellation; meldet sich ein dritter Beobachter an, stimmt das Diagramm nicht mehr (1 Punkt).
  • Schleife über das Interface: Sie zeigt die Struktur des Musters: Der Lagerbestand kennt nur LagerBeobachter und ruft bei allen dieselbe Methode auf, egal wie viele es sind und welche Klasse dahintersteht (Polymorphie). Was die einzelnen Beobachter danach tun, bleibt unsichtbar. Es lässt sich bei Bedarf je Klasse in einem eigenen Diagramm zeigen und mit ref einbinden (1 Punkt).
  • Zweck: Für die Dokumentation des Entwurfs (Wie funktioniert die Kopplung?) passt die Schleife über das Interface; für Tests, Fehlersuche oder das Nachvollziehen eines bestimmten Falls passt der konkrete Ablauf (1 Punkt).

e) Ein Praktikant hat für die Übergabe eines Fertigungsauftrags an die Rahmenwerk OWL GmbH folgendes Diagramm entworfen. Gewünscht ist dieser Ablauf:

  • Sobald eine Bestellung bezahlt ist, erzeugt der Shop einen Fertigungsauftrag fa (Konstruktor mit Bestellnummer und Konfiguration).
  • Der Shop fragt die Terminplanung mit berechneLiefertermin(konfiguration) nach der Lieferzeit in Wochen und wartet auf das Ergebnis.
  • Beträgt die Lieferzeit höchstens 8 Wochen, übermittelt der Shop den Auftrag an das MES (Fertigungssteuerung) von Rahmenwerk OWL, ohne auf die Bearbeitung zu warten. Das MES meldet die Annahme später mit der Auftragsnummer des Partners zurück.
  • Bei mehr als 8 Wochen informiert der Shop die Kundin oder den Kunden über den Mailserver.
Fehlerhafter Entwurf: Sequenzdiagramm zur Übergabe eines Fertigungsauftrags (mit KI erstellt)

Der Entwurf enthält vier Fehler. Benenne die Fehler und korrigiere das Diagramm. (8 Punkte)

Fehler im Entwurf und ihre Korrektur
Nr. Fehler Korrektur
1 fa :Fertigungsauftrag steht oben, als gäbe es das Objekt schon vor dem Ablauf; die Erzeugung ist als synchrone Nachricht gezeichnet. Kopf der Lebenslinie auf Höhe der Erzeugung; new(bestellNr, konfiguration) als gestrichelter Pfeil mit offener Spitze.
2 Die Antwort der Terminplanung ist als durchgezogener Pfeil (wie ein neuer Aufruf) und nur mit dem Wert beschriftet. Gestrichelte Antwort mit Methodenname, Argument und Rückgabewert: berechneLiefertermin(konfiguration): wochen.
3 Die Bedingungen [wochen < 8] und [wochen > 8] lassen genau 8 Wochen aus, obwohl dann übermittelt werden soll. [wochen <= 8] und [else] (oder [wochen > 8]).
4 Auf die asynchrone Nachricht uebermittle(fa) folgt eine Antwort; der Ausführungsbalken des MES suggeriert, dass der Shop wartet. Antworten gibt es nur auf synchrone Nachrichten. Die Rückmeldung des MES ist eine eigene asynchrone Nachricht, z. B. auftragAngenommen(auftragsNr).
Korrigiertes Sequenzdiagramm zur Übergabe eines Fertigungsauftrags (mit KI erstellt)

Punkteverteilung (Vorschlag): je Fehler 1 Punkt für das Benennen und 1 Punkt für die Korrektur. Wer statt Fehler 4 die Nachricht uebermittle synchron macht (Shop wartet auf die Auftragsnummer), erhält die Punkte nur mit Begründung, denn laut Beschreibung soll der Shop nicht warten.

Aufgabe 3.3: Einwilligung, Flurmonitore und Fahrzeugdaten in der Mitfahr-App (Profilkompetenz)

(ca. 35 min Bearbeitungszeit)

Du bist Auszubildende*r und arbeitest im FIA-Projektteam der Mitfahr-App „RatzFahrt“ des Ratz und Rübe Berufskollegs in Bielefeld mit. Die App vermittelt Fahrgemeinschaften zu den Berufsschultagen. Projektleiter Thomas Becker möchte die wichtigsten Abläufe für die Dokumentation als Sequenzdiagramme festhalten. Oksana Melnyk aus dem Projektteam unterstützt Dich.

a) Minderjährige dürfen RatzFahrt nur mit Einwilligung der Erziehungsberechtigten nutzen. Andrea Wolf, die Datenschutzbeauftragte der Schule, beschreibt den Ablauf am Beispiel von Aylin Kaya (17):

  • Aylin registriert sich in der App. Die App teilt ihr sofort mit, dass ihr Konto bis zur Einwilligung gesperrt ist.
  • Aylin bittet im Gespräch ihre Mutter um die Einwilligung. Die Mutter liest die Datenschutzhinweise, unterschreibt das Formular und gibt es Aylin zurück.
  • Aylin legt das Formular in das Postfach von Frau Wolf im Sekretariat. Sie wartet dort nicht auf eine Reaktion.
  • Frau Wolf trägt die Einwilligung über die Verwaltungsoberfläche in der App ein. Die App schaltet das Konto frei und bestätigt Frau Wolf die Speicherung.
  • Anschließend erhält Aylin von der App eine Push-Nachricht, dass ihr Konto freigeschaltet ist.

Stelle den Ablauf in einem UML-Sequenzdiagramm dar. Verwende für die beteiligten Menschen und die App je eine Lebenslinie. Modelliere Gespräche und Bedienvorgänge, bei denen jemand auf das Ergebnis wartet, als synchrone Nachrichten mit Antwort, alles andere als asynchrone Nachrichten. Tätigkeiten, die eine Person oder die App allein ausführt, notierst Du als Selbstaufruf. (12 Punkte)

Beispiellösung: Einwilligungsablauf zwischen Mitfahrerin, Erziehungsberechtigter, Datenschutzbeauftragter und App (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 2 Punkte: je 0,5 Punkte für die vier Lebenslinien mit sinnvollen Namen (Menschen gern als Strichmännchen, die App als Rechteck).
  • 1,5 Punkte: registrieren() synchron mit Antwort „gesperrt bis zur Einwilligung“.
  • 1,5 Punkte: umEinwilligungBitten() synchron mit Antwort (Rückgabe des unterschriebenen Formulars).
  • 1 Punkt: Lesen und Unterschreiben als Selbstaufrufe der Mutter innerhalb ihres Ausführungsbalkens.
  • 1,5 Punkte: formularAbgeben(formular) asynchron (Aylin wartet nicht).
  • 1,5 Punkte: einwilligungEintragen(aylin) synchron mit Antwort „gespeichert“.
  • 0,5 Punkte: kontoFreischalten(aylin) als Selbstaufruf der App.
  • 1,5 Punkte: sendePush(…) asynchron von der App an Aylin.
  • 1 Punkt: richtige zeitliche Reihenfolge.

Hinweis: Im Analyse-Diagramm dürfen die Nachrichten auch umgangssprachlich beschriftet sein („Einwilligung erbitten“, „Formular abgeben“). Entscheidend sind Richtung, Art und Reihenfolge der Nachrichten.

b) Die Flurmonitore zeigen offene Fahrtangebote und Gesuche anonym an. Auf jedem Monitor läuft ein kleiner Player, der seine Daten selbst abruft. Oksana hat die zentrale Methode bereits in Pseudocode geschrieben. Die Klasse MonitorPlayer hat diese Attribute und Methoden:

MonitorPlayer
  - monitorId: Integer
  - laeuft: Boolean
  - fehler: Integer
  - server: MonitorServer
  - anzeige: Bildschirm
  - ticketsystem: Ticketsystem
  + starte(): void
  - formatiereAnonym(eintraege: Eintrag[]): String
  - warte(sekunden: Integer): void

Die Methode starte() kannst Du in vier Pseudocode-Notationen anzeigen; sie sind im Artikel Algorithmen mit Pseudocode dokumentieren beschrieben.

Prozedur starte()
    fehler := 0
    solange laeuft = true
        eintraege: Eintrag[] := server.holeEintraege(monitorId)
        wenn eintraege = null dann
            fehler := fehler + 1
            anzeige.zeigeOffline()
            wenn fehler >= 5 dann
                ticketsystem.meldeStoerung(monitorId) // asynchron
                verlasse Schleife
            Ende wenn
        sonst
            fehler := 0
            text: string := formatiereAnonym(eintraege)
            anzeige.zeige(text)
        Ende wenn
        wenn uhrzeit() >= "17:00" dann
            anzeige.setzeHelligkeit(40)
        Ende wenn
        warte(60)
    Ende solange
Ende starte

Modelliere die Methode starte() als UML-Sequenzdiagramm „sd Flurmonitor aktualisieren“ mit den Lebenslinien player :MonitorPlayer, :MonitorServer, anzeige :Bildschirm und :Ticketsystem. Der Aufruf von starte() kommt von außerhalb des Diagramms. Die Zuweisungen an fehler und die Abfrage der Uhrzeit musst Du nicht als Nachrichten darstellen. (12 Punkte)

Beispiellösung: Schleife alle 60 Sekunden mit Alternative, anschließendem break-Fragment, Selbstaufrufen und opt-Fragment (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 0,5 Punkte: starte() als gefundene Nachricht (von außerhalb, z. B. ausgefüllter Punkt oder Rahmenrand). Ob Du sie synchron (mit Antwort am Ende) oder asynchron zeichnest, hängt davon ab, wie der Player gestartet wird: Ruft ihn das Startprogramm direkt auf, wartet es; startet es ihn in einem eigenen Thread, wartet es nicht. Beides wird anerkannt.
  • 1,5 Punkte: loop-Fragment mit Bedingung ([laeuft == wahr], gern mit dem Hinweis „alle 60 s“).
  • 1 Punkt: holeEintraege(monitorId) mit Antwort eintraege.
  • 1,5 Punkte: alt-Fragment mit [eintraege == null] und [else].
  • 1 Punkt: zeigeOffline() mit Antwort.
  • 1,5 Punkte: break-Fragment direkt im Schleifenrumpf nach dem alt-Fragment mit der Bedingung [eintraege == null und fehler >= 5]: Wird es ausgeführt, entfällt der Rest des Schleifenrumpfs, und die Schleife endet. Ein break innerhalb des alt-Operanden würde nach UML nur diesen Operanden beenden, nicht die Schleife.
  • 1 Punkt: meldeStoerung(monitorId) asynchron.
  • 1 Punkt: formatiereAnonym(eintraege) als Selbstaufruf mit Rückgabewert text.
  • 1 Punkt: zeige(text) mit Antwort.
  • 1 Punkt: opt-Fragment mit [uhrzeit >= 17:00].
  • 0,5 Punkte: setzeHelligkeit(40) im opt-Fragment.
  • 0,5 Punkte: warte(60) als Selbstaufruf am Ende des Schleifenrumpfs.

Hinweise: Statt break darf die Schleifenbedingung [laeuft == wahr und fehler < 5] lauten; dann muss meldeStoerung in einem opt-Fragment stehen (volle Punktzahl). Ein alt-Fragment mit leerem [else]-Zweig statt opt ist ebenfalls richtig.

c) Andrea Wolf hat festgelegt, dass Kennzeichen und Farbe des Fahrzeugs nur Mitfahrende sehen dürfen, deren Buchung für das Angebot bestätigt ist. Alle anderen sehen nur den Fahrzeugtyp und die Zahl der freien Plätze. Oksana setzt das mit dem Stellvertreter-Muster (Proxy) um. Die App kennt nur die Schnittstelle FahrzeugAuskunft; dahinter steckt ein FahrzeugProxy, der das echte Fahrzeug verwaltet:

public interface FahrzeugAuskunft {
    Fahrzeugdaten getDaten(int nutzerId);
}

public class FahrzeugProxy implements FahrzeugAuskunft {
    private final Fahrzeug fahrzeug;          // das echte Objekt, implementiert ebenfalls FahrzeugAuskunft
    private final Buchungsliste buchungen;
    private final int angebotId;
    // Konstruktor ausgelassen

    @Override
    public Fahrzeugdaten getDaten(int nutzerId) {
        if (buchungen.istBestaetigt(nutzerId, angebotId)) {
            return fahrzeug.getDaten(nutzerId);
        }
        return fahrzeug.getOeffentlicheDaten();
    }
}

Zeichne das Sequenzdiagramm für einen Aufruf von getDaten(nutzerId) durch die App mit beiden möglichen Verläufen. Verwende die Lebenslinien :App, proxy :FahrzeugProxy, :Buchungsliste und fz :Fahrzeug. (7 Punkte)

Beispiellösung: Die App fragt den FahrzeugProxy; der Proxy prüft die Buchung bei der Buchungsliste und holt je nach Ergebnis die vollständigen oder nur die öffentlichen Daten vom Fahrzeug (mit KI erstellt)

Punkteverteilung (Vorschlag):

  • 1 Punkt: getDaten(nutzerId) von der App an den Proxy.
  • 1 Punkt: istBestaetigt(nutzerId, angebotId) an die Buchungsliste mit Rückgabewert.
  • 1,5 Punkte: alt-Fragment mit Bedingung (z. B. [ok == true]) und [else].
  • 1 Punkt: Weiterleitung getDaten(nutzerId) an fz mit Antwort im ersten Operanden.
  • 1 Punkt: getOeffentlicheDaten() an fz mit Antwort im zweiten Operanden.
  • 1 Punkt: Antworten des Proxys an die App in beiden Operanden.
  • 0,5 Punkte: Ausführungsbalken (Proxy während des gesamten Aufrufs aktiv).

Hinweis: Die Prüfung steht im Code direkt in der if-Bedingung. Ein Selbstaufruf des Proxys wäre hier falsch, weil der Proxy keine eigene Methode für die Prüfung aufruft.

d) Andrea Wolf verlangt zusätzlich, dass jeder Abruf der vollständigen Fahrzeugdaten protokolliert wird. Oksana hat die Änderung zuerst im Sequenzdiagramm entworfen:

Entwurf: Nach der Weiterleitung an das Fahrzeug sendet der Proxy die Nachricht vermerke(nutzerId, angebotId) an das Zugriffsprotokoll (mit KI erstellt)

Passe die Methode getDaten aus c) so an, dass sie dem Entwurf entspricht. Das Protokoll bietet die Methode vermerke(nutzerId, angebotId). Begründe, an welchem Merkmal des Diagramms Du erkennst, wie Du den Aufruf umsetzen musst. (4 Punkte)

@Override
public Fahrzeugdaten getDaten(int nutzerId) {
    if (buchungen.istBestaetigt(nutzerId, angebotId)) {
        Fahrzeugdaten daten = fahrzeug.getDaten(nutzerId);
        CompletableFuture.runAsync(() -> protokoll.vermerke(nutzerId, angebotId));
        return daten;
    }
    return fahrzeug.getOeffentlicheDaten();
}

Punkteverteilung (Vorschlag):

  • 1 Punkt: Ergebnis von fahrzeug.getDaten(nutzerId) zwischenspeichern, weil der Vermerk laut Diagramm nach der Weiterleitung und vor der Antwort an die App kommt.
  • 1 Punkt: Vermerk nur im Zweig mit bestätigter Buchung; der else-Zweig bleibt unverändert.
  • 2 Punkte: Begründung: vermerke ist als asynchrone Nachricht gezeichnet (offene Pfeilspitze, keine Antwort). Der Proxy wartet also nicht auf das Protokoll, sondern antwortet sofort der App. Im Code geschieht das z. B. mit CompletableFuture.runAsync(…), über eine Warteschlange oder einen eigenen Thread. Ein einfacher Methodenaufruf protokoll.vermerke(…) wäre in Java synchron und erhält nur 1 Punkt für die Umsetzung, wenn die Begründung den Unterschied nennt.

Das Attribut protokoll (Typ Zugriffsprotokoll) muss im Proxy ergänzt werden.

e) Im Teamgespräch schlägt jemand vor, auf den Proxy zu verzichten: Die App soll selbst prüfen, ob die Buchung bestätigt ist, und dann je nach Ergebnis getDaten oder getOeffentlicheDaten direkt am Fahrzeug aufrufen. Bewerte diesen Vorschlag. (3 Punkte)

Der Vorschlag ist abzulehnen (1 Punkt für eine begründete Entscheidung), zum Beispiel weil:

  • die App auf dem Gerät der Nutzenden läuft und manipuliert werden kann; eine Zugriffsregel des Datenschutzes muss auf dem Server durchgesetzt werden (1 Punkt),
  • jeder weitere Client (Flurmonitor, Webseite) die Prüfung und die Protokollierung wiederholen müsste; beim Proxy steht die Regel an genau einer Stelle, und der Client sieht weiter nur FahrzeugAuskunft (1 Punkt).

Ein Vorteil des Vorschlags wäre nur ein Aufruf weniger; das wiegt die Nachteile nicht auf.


Hinweis zur Nachnutzung als Open Educational Resource (OER)

Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Übungsaufgaben zum UML-Sequenzdiagramm” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/uml-sequenzdiagramm-uebungsaufgaben veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/uml/uml-diagramme. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 29.10.2026.

[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: