Übungsaufgaben zum Entwurfsmuster Fabrikmethode

https://bildung.social/@oerinformatik/

https://oer-informatik.de/entwurfsmuster-fabrikmethode-uebungsaufgaben

Fabrikmethode, Entwurfsmuster, Erzeugungsmuster, Factory Method, statische Fabrikmethode, Polymorphie, UML-Klassendiagramm, Singleton, Übungsaufgaben, Prüfungsvorbereitung

tl/dr; (Bearbeitungszeit insgesamt 59 min, mehrere Aufgaben): Zwei umfangreiche Übungsaufgaben zur Fabrikmethode: Teilnahmebestätigungen je Aktivitätsart in einer Freizeit-App (Rollen mit Belegen aus einer englischen Architekturentscheidung, Erweiterung um eine Kategorie, Pseudocode, Fehlersuche im Java-Code) und Einträge auf den Flurmonitoren einer Mitfahr-App (Fallunterscheidungen durch Polymorphie und eine statische Fabrikmethode ersetzen, Fehlersuche, Ablauf und Erweiterung einer parametrisierten Fabrikmethode, Singleton oder Übergabe). Alle Lösungen sind ausgeblendet und mit Punkteverteilung versehen [AI-Assisted]. (Zuletzt geändert am 28.10.2026)

Diese Übungsaufgaben gehören zum Artikel Entwurfsmuster Fabrikmethode. Sie bauen auf den Artikeln Entwurfsmuster und Polymorphie auf.

Hinweise zur Bearbeitung: Von FIA wird erwartet, dass ihnen Aufgaben auf Profilkompetenz-Ebene (Aufgabe 3.1 und Aufgabe 3.2) keine Probleme bereiten. Zeichne Deine Ergänzungen der Klassendiagramme auf Papier oder mit einem Werkzeug Deiner Wahl, bevor Du die Beispiellösung aufklappst. Pseudocode muss keiner bestimmten Sprache folgen, aber erkennbar mit Objekten, Methodenaufrufen, new und Rückgaben arbeiten; wo „Pseudocode oder Struktogramm“ steht, ist beides richtig. Als Datentypen sind UML-Typen (Integer, Real, Boolean, String) ebenso richtig wie die Typen einer Programmiersprache. Andere fachlich richtige Lösungen sind ebenfalls richtig.

Die Beispiellösungen zeigen den Pseudocode in vier Notationen (JANA, Pseudo-Pascal, Pseudo-Pascal deutsch, Pseudo-Python), zwischen denen Du über die Reiter wechselst; für Deine eigenen Lösungen kannst Du eine davon wählen. Die Notationen sind im Artikel Algorithmen mit Pseudocode dokumentieren beschrieben. Eine Zuweisung sieht zum Beispiel so aus:

alter: integer := b.getAlter()

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 „Entwurfsmuster Fabrikmethode“.

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/entwurfsmuster-fabrikmethode
- https://oer-informatik.de/entwurfsmuster
- https://oer-informatik.de/uml-klassendiagramm-polymorphie
- Stilbeispiel: https://oer-informatik.de/entwurfsmuster-fabrikmethode-uebungsaufgaben

Die Aufgaben sollen Inhalte zu diesen Schlagwörtern abdecken:
- Fabrikmethode
- Entwurfsmuster
- Erzeugungsmuster
- Factory Method
- statische Fabrikmethode
- Polymorphie
- UML-Klassendiagramm
- Singleton

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 3.1: Teilnahmebestätigungen in einer Freizeit-App (Profilkompetenz)

(ca. 27 min Bearbeitungszeit)

Du bist Auszubildende*r im Entwicklungsteam der Let’s Meet GmbH in Bielefeld. Wer sich in der App „Let’s Meet“ zu einer Aktivität anmeldet, bekommt eine Teilnahmebestätigung per Push-Nachricht und E-Mail. Je nach Art der Aktivität soll die Bestätigung andere Hinweise enthalten: Bei Naturaktivitäten wie der Sonntagswanderung von Sabine Hoffmann gehören ein Wetterhinweis und „festes Schuhwerk“ hinein, bei Sportaktivitäten wie dem Feierabend-Kick von Malik Haddad der Kostenbeitrag und „Sportkleidung mitbringen“. Dr. Marta Kowalczyk, die Datenschutzbeauftragte, hat vorgegeben, dass eine Bestätigung keine Namen anderer Teilnehmender enthalten darf.

Yusuf Demir, Leiter der Entwicklung, hat seine Architekturentscheidung im englischsprachigen Team-Wiki festgehalten (in der Entwicklung arbeiten auch Kolleg*innen, die kein Deutsch sprechen):

ADR-017: Participation confirmations with the Factory Method pattern

Status: accepted. Author: Yusuf Demir

Context: Every activity category needs its own participation confirmation. Outdoor activities include a weather notice, sports activities include the fee and a reminder to bring sports clothes. More categories will follow next year.

Decision: We apply the Factory Method pattern, a creational pattern. The abstract class Aktivitaet declares the factory method erzeugeBestaetigung(). Its return type is the abstract class Teilnahmebestaetigung. Each subclass of Aktivitaet overrides the factory method and decides which concrete confirmation class is instantiated. The method anmelden() is implemented only once, in Aktivitaet. It calls the factory method instead of a constructor and works with the abstract type only.

Consequences: A new category requires two new classes, but no change to anmelden(). Every confirmation class must be derived from Teilnahmebestaetigung – otherwise the overriding factory method cannot return its objects. The number of classes grows with every category.

Das Klassenmodell sieht bisher so aus (Ausschnitt; die Klasse Benutzer ist nicht dargestellt):

Vorgegebenes Klassendiagramm: abstrakte Klasse Aktivitaet mit anmelden() und abstrakter erzeugeBestaetigung(), Unterklassen Naturaktivitaet und Sportaktivitaet; abstrakte Klasse Teilnahmebestaetigung mit getText() und senden(), Unterklassen Naturbestaetigung und Sportbestaetigung (mit KI erstellt)
  1. Werte die Architekturentscheidung aus.

aa) Ordne den Rollen der Fabrikmethode die Klassen aus dem Klassenmodell zu. Belege jede Zuordnung mit dem passenden Satz oder Satzteil aus ADR-017 (englisch zitiert oder sinngemäß auf Deutsch). (6 Punkte)

Rollen der Fabrikmethode im Klassenmodell (zum Ausfüllen)
Rolle Klasse(n) Beleg aus ADR-017
Erzeuger (Creator)
Konkreter Erzeuger (ConcreteCreator)
Produkt (Product)
Konkretes Produkt (ConcreteProduct)

Je Zeile 0,5 Punkte für die Klasse(n) und 1 Punkt für einen passenden Beleg:

Lösung: Rollen der Fabrikmethode im Klassenmodell
Rolle Klasse(n) Beleg aus ADR-017
Erzeuger (Creator) Aktivitaet „The abstract class Aktivitaet declares the factory method …“ und „The method anmelden() is implemented only once, in Aktivitaet.“
Konkreter Erzeuger (ConcreteCreator) Naturaktivitaet, Sportaktivitaet „Each subclass of Aktivitaet overrides the factory method and decides which concrete confirmation class is instantiated.“
Produkt (Product) Teilnahmebestaetigung „Its return type is the abstract class Teilnahmebestaetigung.“ bzw. „works with the abstract type only“
Konkretes Produkt (ConcreteProduct) Naturbestaetigung, Sportbestaetigung „… decides which concrete confirmation class is instantiated“ bzw. „Every confirmation class must be derived from Teilnahmebestaetigung“

Andere passende Belege sind ebenfalls richtig.

ab) Nenne die Kategorie, zu der ADR-017 die Fabrikmethode zählt, und zwei weitere Entwurfsmuster dieser Kategorie. (2 Punkte)

  • Kategorie (1 Punkt): Erzeugungsmuster (creational pattern).

  • Zwei weitere (je 0,5 Punkte): Singleton, Abstrakte Fabrik (Abstract Factory), Erbauer (Builder), Prototyp (Prototype).

  1. Ab Januar 2027 sollen Sprachtandems wie das Tandem Deutsch–Arabisch von Malik Haddad eine eigene Kategorie „Sprache“ bekommen. Ihre Bestätigung nennt die beiden Sprachen und den Hinweis „Bitte teilt die Zeit gleichmäßig auf beide Sprachen auf.“

Beschreibe, welche Klassen für die neue Kategorie entstehen, von welcher Klasse sie jeweils erben und welche Methoden sie überschreiben bzw. neu erhalten. Nenne außerdem eine Methode, die unverändert bleibt, und begründe das mit ADR-017. (5 Punkte)

Lösung: Das Klassenmodell ist um die Klasse Sprachaktivitaet mit überschriebener erzeugeBestaetigung() (erbt von Aktivitaet) und die Klasse Sprachbestaetigung mit Konstruktor und getText() (erbt von Teilnahmebestaetigung) ergänzt; Sprachaktivitaet erzeugt Sprachbestaetigung (mit KI erstellt)

Bewertung:

  • 2 Punkte für Sprachaktivitaet: erbt von Aktivitaet (1) und überschreibt #erzeugeBestaetigung(b: Benutzer): Teilnahmebestaetigung, die eine Sprachbestaetigung zurückgibt (1).

  • 2 Punkte für Sprachbestaetigung: erbt von Teilnahmebestaetigung (1), erhält einen Konstruktor und überschreibt +getText(): String mit den beiden Sprachen und dem Hinweis (1).

  • 1 Punkt für die unveränderte Methode: anmelden() in Aktivitaet bleibt gleich, weil sie laut ADR-017 nur die Fabrikmethode aufruft und mit dem abstrakten Typ Teilnahmebestaetigung arbeitet („no change to anmelden()“).

Das Diagramm zeigt die Ergänzung im Klassenmodell. Eine Zeichnung ist nicht gefordert.

Die «Create»-Abhängigkeit von Sprachaktivitaet zu Sprachbestaetigung ist sinnvoll, aber nicht gefordert. Ein Attribut für die Sprachen (z. B. -sprachen: String [2] in Sprachaktivitaet) ist richtig, aber ebenfalls nicht gefordert.

  1. Implementiere in Pseudocode die Methode anmelden(b: Benutzer): Teilnahmebestaetigung der Klasse Aktivitaet. Ist die Person jünger als das Mindestalter der Aktivität, gibt die Methode null zurück. Sonst erzeugt sie mithilfe der Fabrikmethode die passende Bestätigung, versendet sie und gibt sie zurück. Das Alter liefert b.getAlter(). (5 Punkte)

Funktion anmelden(b: Benutzer): Teilnahmebestaetigung
    wenn b.getAlter() < mindestalter dann
        Rückgabe null
    Ende wenn
    bestaetigung: Teilnahmebestaetigung := erzeugeBestaetigung(b)
    bestaetigung.senden()
    Rückgabe bestaetigung
Ende anmelden

Bewertung:

  • 1 Punkt Altersprüfung mit Rückgabe null

  • 2 Punkte Aufruf der Fabrikmethode mit Übergabe von b und Speichern in einer Variablen vom Typ Teilnahmebestaetigung

  • 1 Punkt Aufruf senden() am erzeugten Objekt

  • 1 Punkt Rückgabe der Bestätigung

Kein Punkt für den Aufruf eines Konstruktors (new Naturbestaetigung(...)) in anmelden(): Genau das soll die Fabrikmethode vermeiden.

  1. Implementiere in Pseudocode die Methode erzeugeBestaetigung(b: Benutzer): Teilnahmebestaetigung der Klasse Sprachaktivitaet und erläutere, welches Objekt Du als zweites Argument an den Konstruktor übergibst. (3 Punkte)

Funktion erzeugeBestaetigung(b: Benutzer): Teilnahmebestaetigung
    Rückgabe new Sprachbestaetigung(b, this)
Ende erzeugeBestaetigung
  • 1 Punkt Objekterzeugung einer Sprachbestaetigung

  • 1 Punkt Rückgabe

  • 1 Punkt Erläuterung: Mit this (in Pseudo-Python self) übergibt die Aktivität sich selbst. Die Bestätigung kennt damit „ihre“ Aktivität und kann Titel, Treffpunkt, Beginn und die Sprachen für den Text abfragen.

  1. Jonas Weber, Dein Mit-Azubi, hat schon einmal eine Kategorie „Kultur“ (Konzerte, Kino, Chor) vorbereitet. Sein Java-Code lässt sich nicht übersetzen und widerspricht außerdem dem Muster:
public class Kulturaktivitaet extends Aktivitaet {
    @Override
    protected Teilnahmebestaetigung erzeugeBestaetigung(Benutzer b) {
        return new Teilnahmebestaetigung(b, this);
    }
}

public class Kulturbestaetigung {
    public Kulturbestaetigung(Benutzer b, Aktivitaet a) { /* ... */ }
    public String getText() { /* Einlass, Ticket, Garderobe ... */ }
}

// geänderte Methode in Aktivitaet:
public Teilnahmebestaetigung anmelden(Benutzer b) {
    if (b.getAlter() < mindestalter) {
        return null;
    }
    Teilnahmebestaetigung t;
    if (this instanceof Kulturaktivitaet) {
        t = new Kulturbestaetigung(b, this);
    } else {
        t = erzeugeBestaetigung(b);
    }
    t.senden();
    return t;
}

Beschreibe drei Fehler und gib jeweils an, wie sie behoben werden. (6 Punkte)

Je Fehler 1 Punkt Beschreibung, 1 Punkt Korrektur:

  1. Objekt einer abstrakten Klasse: In Kulturaktivitaet.erzeugeBestaetigung() wird new Teilnahmebestaetigung(...) aufgerufen. Von der abstrakten Klasse lassen sich keine Objekte erzeugen (Übersetzungsfehler). Korrektur: return new Kulturbestaetigung(b, this);

  2. Kein gemeinsamer Obertyp: Kulturbestaetigung erbt nicht von Teilnahmebestaetigung. Ihre Objekte können weder t zugewiesen noch von der Fabrikmethode zurückgegeben werden (Übersetzungsfehler, genau die Einschränkung aus ADR-017). Korrektur: public class Kulturbestaetigung extends Teilnahmebestaetigung, im Konstruktor super(b, a); aufrufen und getText() überschreiben (@Override).

  3. Fallunterscheidung und Konstruktoraufruf im Erzeuger: anmelden() prüft mit instanceof die konkrete Unterklasse und erzeugt die Kulturbestätigung selbst. Damit kennt die Oberklasse wieder konkrete Klassen und muss für jede neue Kategorie geändert werden – das Muster wird ausgehebelt. Korrektur: Die if-Anweisung entfernen; anmelden() ruft immer t = erzeugeBestaetigung(b); auf, die Entscheidung trifft die überschreibende Methode in Kulturaktivitaet.

  1. Erläutere, warum erzeugeBestaetigung() in der Klasse Aktivitaet abstrakt und mit der Sichtbarkeit protected (#) deklariert ist. Beschreibe außerdem, wann statt einer abstrakten Methode eine Standardimplementierung in Aktivitaet sinnvoll sein kann. (3 Punkte)
  • abstrakt (1 Punkt): Aktivitaet kann nicht wissen, welche Bestätigung passt. Die abstrakte Methode zwingt jede (nicht abstrakte) Unterklasse, die Fabrikmethode zu implementieren; eine neue Kategorie ohne Bestätigung fällt schon beim Übersetzen auf. Zugleich muss Aktivitaet dadurch selbst abstrakt sein; es gibt also keine „Aktivität ohne Kategorie“.

  • protected (1 Punkt): Die Methode ist ein internes Hilfsmittel von anmelden(). Von außen soll niemand eine Bestätigung erzeugen, ohne dass das Alter geprüft und die Bestätigung versendet wird. Unterklassen müssen sie aber sehen und überschreiben können.

  • Standardimplementierung (1 Punkt): wenn es eine sinnvolle allgemeine Bestätigung gibt (z. B. eine StandardBestaetigung mit Titel, Treffpunkt und Beginn), die die meisten Kategorien nutzen können. Dann überschreiben nur Kategorien mit Besonderheiten die Methode; der Erzeuger ist in diesem Fall eine konkrete Klasse.

Aufgabe 3.2: Einträge für die Flurmonitore einer Mitfahr-App (Profilkompetenz)

(ca. 32 min Bearbeitungszeit)

Du bist Auszubildende*r im Projektteam der Mitfahr-App „RatzFahrt“ des Ratz und Rübe Berufskollegs in Bielefeld. Die vier Flurmonitore zeigen offene Angebote und Gesuche anonym an. Die Software auf den Mini-Playern ruft dazu die Datenbanksicht v_monitor ab (Spalten art, ort, treffpunkt, richtung, datum, zeit, plaetze; art ist 'Angebot' oder 'Gesuch') und legt für jede Ergebniszeile ein Objekt an. Jonas Wolff hat die Klasse dafür so geschrieben:

public class MonitorEintrag {
    private String art;                 // "Angebot" oder "Gesuch"
    private String treffpunkt;
    private String richtung;
    private String zeit;
    private int plaetze;

    public MonitorEintrag(Zeile z) {
        art = z.getText("art");
        treffpunkt = z.getText("treffpunkt");
        richtung = z.getText("richtung");
        zeit = z.getText("zeit");
        plaetze = z.getZahl("plaetze");
    }

    public String kachelText() {
        switch (art) {
            case "Angebot": return "Biete: " + treffpunkt + ", " + zeit + " Uhr, " + plaetze + " frei";
            case "Gesuch":  return "Suche: " + treffpunkt + ", " + zeit + " Uhr";
            default:        return "";
        }
    }

    public String farbe() {
        switch (art) {
            case "Angebot": return "#38A169";   // Grün
            case "Gesuch":  return "#2B6CB0";   // Schulblau
            default:        return "#FFFFFF";
        }
    }
}

// im Player:
for (Zeile zeile : ergebnis) {
    eintraege.add(new MonitorEintrag(zeile));
}

Thomas Becker möchte, dass künftig auch Pendelangebote angezeigt werden: regelmäßige Fahrten an festen Wochentagen bis zum Schuljahresende. Die Sicht v_monitor soll dafür um die Art 'Pendel' und eine Spalte wochentage (z. B. 'Mo,Do') erweitert werden. Ein Pendelangebot ist ein Angebot mit freien Plätzen; auf der Kachel steht zusätzlich „jeden Mo, Do“.

  1. Beschreibe zwei Nachteile der vorliegenden Umsetzung im Hinblick auf die Wartbarkeit, insbesondere bei der Ergänzung der Pendelangebote. (4 Punkte)

Je Nachteil 2 Punkte, z. B.:

  • Redundante Fallunterscheidungen: Dieselbe switch-Struktur über art steht in mehreren Methoden. Für die Pendelangebote muss jede dieser Methoden geändert werden; wird eine vergessen, ist das Verhalten widersprüchlich.

  • Fehler fallen nicht auf: Kommt eine Zeile mit 'Pendel' an, bevor der Code angepasst ist, liefert kachelText() still einen leeren Text und farbe() Weiß – auf dem Monitor erscheint eine leere weiße Kachel, ohne Fehlermeldung. Tippfehler in den Zeichenketten fallen ebenfalls erst zur Laufzeit auf.

  • Unnötige Attribute: Jedes Objekt trägt alle Attribute, auch wenn sie für seine Art keine Bedeutung haben (plaetze bei Gesuchen, künftig wochentage bei allen).

  • Geprüfter Code wird geändert: Jede Erweiterung ändert die bestehende, getestete Klasse statt nur neuen Code hinzuzufügen (Verstoß gegen das Offen-geschlossen-Prinzip); die Klasse wird mit jeder Art länger.

  1. Oksana Melnyk schlägt vor, statt der switch-Anweisungen für jede Art eine eigene Unterklasse von MonitorEintrag anzulegen. Die Objekte soll künftig eine statische Methode erzeuge(z: Zeile) in MonitorEintrag liefern. Zeichne ein UML-Klassendiagramm für diesen Ansatz mit allen Attributen und Methoden. Entscheide selbst, ob ein Pendelangebot von der Klasse für Angebote oder direkt von MonitorEintrag erbt, und begründe Deine Entscheidung. (8 Punkte)
Lösung: abstrakte Klasse MonitorEintrag mit Attributen treffpunkt, richtung, zeit, geschütztem Konstruktor, unterstrichener statischer Methode erzeuge(z: Zeile): MonitorEintrag und abstrakten Methoden kachelText() und farbe(); Unterklassen AngebotEintrag (plaetze) und GesuchEintrag; PendelEintrag (wochentage) erbt von AngebotEintrag und überschreibt nur kachelText() (mit KI erstellt)

Bewertung:

  • 2 Punkte Oberklasse: MonitorEintrag abstrakt, ohne Attribut art, mit den gemeinsamen Attributen und den abstrakten Methoden kachelText() und farbe()

  • 1 Punkt statische Methode erzeuge(z: Zeile): MonitorEintrag (unterstrichen bzw. {static})

  • 3 Punkte Unterklassen für Angebote, Gesuche und Pendelangebote, jeweils mit ihren eigenen Attributen (plaetze, wochentage) und den Methoden, die sie überschreiben

  • 1 Punkt Generalisierungen

  • 1 Punkt Begründung der Entscheidung für das Pendelangebot

Richtig ist auch, PendelEintrag direkt von MonitorEintrag erben zu lassen; dann braucht die Klasse ein eigenes Attribut plaetze und eine eigene farbe(). Die Vererbung von AngebotEintrag vermeidet diese Doppelung. Das Attribut plaetze kann auch in der Oberklasse bleiben.

Jonas Wolff hat erzeuge bereits programmiert:

statisch Funktion erzeuge(z: Zeile): MonitorEintrag
    art: string := z.getText("art")
    wenn art = "Gesuch" dann
        Rückgabe new GesuchEintrag(z)
    Ende wenn
    Rückgabe new AngebotEintrag(z)
Ende erzeuge

Beim Test zeigt der Monitor Pendelangebote ohne den Zusatz „jeden Mo, Do“, und eine versehentlich eingetragene Zeile mit der Art 'Test' erscheint als grüne Angebotskachel.

  1. Erkläre die Ursachen beider Fehler und gib eine korrigierte Fassung von erzeuge in Pseudocode oder als Struktogramm an. Für eine unbekannte Art soll null zurückgegeben werden. (5 Punkte)

Ursachen (2 Punkte): Jonas prüft nur auf "Gesuch"; alles andere wird zu einem AngebotEintrag. Ein Pendelangebot ist damit ein gewöhnliches Angebot, dessen kachelText() die Wochentage nicht kennt (1 Punkt). Auch jede unbekannte Art landet im letzten Zweig und wird still als Angebot angezeigt, statt aufzufallen (1 Punkt).

Korrigierte Fassung (3 Punkte):

statisch Funktion erzeuge(z: Zeile): MonitorEintrag
    falls z.getText("art")
        "Angebot":
            Rückgabe new AngebotEintrag(z)
        "Gesuch":
            Rückgabe new GesuchEintrag(z)
        "Pendel":
            Rückgabe new PendelEintrag(z)
        sonst:
            Rückgabe null
    Ende falls
Ende erzeuge

Als Struktogramm mit verschachtelten Verzweigungen (eine Fallauswahl mit vier Spalten ist ebenso richtig):

Struktogramm der statischen Methode erzeuge: art wird aus der Zeile gelesen, dann prüfen drei verschachtelte Verzweigungen auf Angebot, Gesuch und Pendel und geben das passende neue Objekt zurück, sonst null (mit KI erstellt)

Bewertung:

  • 1 Punkt eigener Fall für "Pendel" mit PendelEintrag

  • 1 Punkt Angebote und Gesuche nur bei passender Art

  • 1 Punkt Rückgabe null für jede andere Art

In Java würde man für eine unbekannte Art oft eine Ausnahme werfen (throw new IllegalArgumentException(...)) oder den Fehler protokollieren; Bleibt es bei null, muss der Player diesen Wert vor dem Hinzufügen abfangen.

  1. Gib die geänderte Anweisung in der Schleife des Players an. Erläutere außerdem zwei Maßnahmen bzw. Eigenschaften, die dafür sorgen, dass Einträge nur noch über erzeuge angelegt werden. (3 Punkte)
  • Anweisung (1 Punkt): eintraege.add(MonitorEintrag.erzeuge(zeile)); – Aufruf über den Klassennamen, weil die Methode statisch ist (ggf. mit Prüfung auf null).

  • Maßnahmen (je 1 Punkt, zwei davon):

    • MonitorEintrag ist abstrakt, new MonitorEintrag(zeile) ist also nicht mehr möglich.

    • Die Konstruktoren der Unterklassen sind nicht öffentlich, sondern paketsichtbar (~) oder protected; MonitorEintrag mit der Fabrikmethode und die Unterklassen liegen im selben Paket, der Player in einem anderen.

    • Der Rückgabetyp ist MonitorEintrag: Der Player kennt die Unterklassen gar nicht und braucht sie nicht.

  1. Svenja Krämer weist darauf hin, dass der 32-Zoll-Monitor am Ausgang Parkplatz C kleiner ist als die übrigen (43 bzw. 55 Zoll). Dort sollen alle Einträge als einheitliche Kompaktkachel erscheinen; auf den großen Monitoren gibt es eigene Kacheln für Angebote und Gesuche. Das Team hat dafür folgenden Entwurf erstellt. MonitorEintrag bietet dazu zusätzlich die Methode getArt(): String an, die "Angebot" oder "Gesuch" liefert (für Pendelangebote "Angebot"). erstelleKachel(e) ist in Kachelfabrik fertig implementiert: Sie ruft neueKachel(e.getArt()) auf, befüllt die erhaltene Kachel mit befuellen(e) und gibt sie zurück.
Vorgegebenes Klassendiagramm: Monitorsteuerung aggregiert eine abstrakte Kachelfabrik mit erstelleKachel(e: MonitorEintrag): Kachel und abstrakter neueKachel(art: String): Kachel; Unterklassen Grossformatfabrik (erzeugt GrossAngebotKachel und GrossGesuchKachel) und Kompaktfabrik (erzeugt KompaktKachel); abstrakte Klasse Kachel mit befuellen() und zeichnen() (mit KI erstellt)

ea) Am Ausgang Parkplatz C ist der Monitorsteuerung eine Kompaktfabrik zugeordnet. Beschreibe der Reihe nach, welche Methoden bei welchen Objekten ablaufen, wenn sie dort für ein Gesuch erstelleKachel(e) aufruft, und welche Kachel am Ende entsteht. (3 Punkte)

  • Aufrufkette (1 Punkt): Die Monitorsteuerung ruft erstelleKachel(e) an ihrem Fabrikobjekt auf. Die Methode ist in Kachelfabrik implementiert und wird geerbt. Sie fragt e.getArt() ab (Ergebnis "Gesuch") und ruft neueKachel("Gesuch") auf.

  • Wer entscheidet (1 Punkt): Weil das Fabrikobjekt eine Kompaktfabrik ist, läuft deren überschriebene neueKachel (späte Bindung). Sie wertet die Art gar nicht aus und erzeugt immer eine KompaktKachel.

  • Ergebnis (1 Punkt): erstelleKachel ruft an dieser Kachel befuellen(e) auf und gibt eine befüllte KompaktKachel an die Monitorsteuerung zurück. Die Monitorsteuerung kennt dabei nur den Typ Kachel.

eb) Für einen Hochkant-Monitor im Foyer ist eine dritte Fabrik geplant: Angebote (auch Pendelangebote) sollen als HochkantAngebotKachel erscheinen, alle anderen Einträge als KompaktKachel. Gib an, welche Klassen und Beziehungen im Entwurf hinzukommen, und implementiere die Methode neueKachel(art: String): Kachel der neuen Fabrik in Pseudocode. (4 Punkte)

Ergänzungen im Entwurf (2 Punkte): eine Klasse Hochkantfabrik, die von Kachelfabrik erbt und #neueKachel(art: String): Kachel überschreibt (1 Punkt); eine Klasse HochkantAngebotKachel, die von Kachel erbt und zeichnen() überschreibt, dazu «Create»-Abhängigkeiten von Hochkantfabrik zu HochkantAngebotKachel und KompaktKachel (1 Punkt). Monitorsteuerung, Kachelfabrik und die übrigen Kacheln bleiben unverändert.

Methode (2 Punkte):

Funktion neueKachel(art: string): Kachel
    wenn art = "Angebot" dann
        Rückgabe new HochkantAngebotKachel()
    Ende wenn
    Rückgabe new KompaktKachel()
Ende neueKachel

Bewertung: 1 Punkt Verzweigung über art, 1 Punkt beide Rückgaben mit Objekterzeugung. Weil getArt() für Pendelangebote "Angebot" liefert, braucht es keinen eigenen Fall dafür.

ec) Erläutere am Beispiel zwei Unterschiede zwischen der Fabrikmethode neueKachel() der Kachelfabriken und der statischen Methode erzeuge() aus Teilaufgabe c). (4 Punkte)

Je Unterschied 2 Punkte, z. B.:

  • Wer entscheidet über die Klasse? Bei den Kachelfabriken entscheidet die Unterklasse des Erzeugers (Grossformatfabrik oder Kompaktfabrik), welche Kachel entsteht; erstelleKachel() in der Oberklasse kennt nur Kachel. Bei erzeuge() trifft eine einzige Methode die Entscheidung über eine Mehrfachauswahl, eine Erzeuger-Hierarchie gibt es nicht.

  • Objektmethode vs. Klassenmethode: neueKachel() ist eine (abstrakte, überschreibbare) Methode, die an einem Fabrikobjekt aufgerufen wird; welche Implementierung läuft, entscheidet sich zur Laufzeit (späte Bindung). erzeuge() ist statisch, wird über den Klassennamen aufgerufen und kann nicht überschrieben werden.

  • Erweiterung: Für einen neuen Monitortyp (z. B. Hochformat) wird bei den Kachelfabriken nur eine neue Fabrik mit ihren Kacheln ergänzt, Monitorsteuerung und erstelleKachel() bleiben unverändert. Für eine neue Eintragsart muss dagegen erzeuge() geändert werden.

  • Einordnung: Die Kachelfabriken setzen das GoF-Muster Fabrikmethode um; die statische Methode ist eine statische Fabrikmethode (kein GoF-Muster, sondern ein Programmieridiom).

  1. Für die Verbindung zur Datenbank soll es im Player nur ein einziges Verbindungsobjekt geben. Oksana möchte dafür das Erzeugungsmuster Singleton einsetzen. Jonas schlägt vor, das Verbindungsobjekt beim Start des Players einmal zu erzeugen und an alle Klassen zu übergeben, die es brauchen. Vergleiche beide Vorschläge, indem Du je einen Vorteil und einen Nachteil nennst, und triff eine begründete Entscheidung. (4 Punkte)
  • Singleton (1,5 Punkte): Vorteil: Die Klasse selbst stellt sicher, dass es nur ein Objekt gibt (privater Konstruktor, statische Zugriffsmethode); jede Klasse kommt ohne zusätzliche Parameter an die Verbindung. Nachteil: Die Verbindung ist ein globaler Zugriffspunkt. Welche Klassen sie nutzen, sieht man den Signaturen nicht an, und für Tests lässt sie sich schwer durch eine Testverbindung ersetzen.

  • Übergeben (1,5 Punkte): Vorteil: Abhängigkeiten stehen sichtbar im Konstruktor, und für Tests kann man leicht eine andere Verbindung übergeben. Nachteil: Dass es nur ein Objekt gibt, beruht auf Disziplin; mehrere Konstruktoren erhalten einen zusätzlichen Parameter.

  • Entscheidung (1 Punkt), z. B.: Für den kleinen Player ist das Übergeben gut beherrschbar und besser testbar; wer viele Klassen hat, die die Verbindung brauchen, kann den Singleton wählen. Jede schlüssig begründete Entscheidung ist richtig.


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 Entwurfsmuster Fabrikmethode” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/entwurfsmuster-fabrikmethode-uebungsaufgaben veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/design-pattern/entwurfsmuster. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 28.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: