Carsharing
AFB I–IIEin Carsharing-Anbieter lässt eine Verwaltungssoftware entwickeln. Die Anforderungen stehen im Kasten.
(1) Der Anbieter betreibt mehrere Stationen; jede Station hat einen Namen. (2) An jeder Station stehen bis zu zehn Fahrzeuge. (3) Jedes Fahrzeug hat ein Kennzeichen und einen Preis pro Minute. (4) Elektroautos sind Fahrzeuge, bei denen zusätzlich der Akkustand in Prozent gespeichert wird. (5) Kunden haben einen Namen und eine Führerscheinnummer. (6) Eine Buchung gehört zu genau einem Kunden und genau einem Fahrzeug und speichert die gefahrenen Minuten; aus ihr lassen sich die Kosten berechnen. (7) Jeder Kunde soll alle seine Buchungen einsehen können.
- Erstellen Sie ein Klassendiagramm, das die Anforderungen (1) bis (7) erfüllt. Geben Sie Attribute mit Datentypen, die für (6) und (7) nötigen Methoden sowie alle Beziehungen mit Richtung und Kardinalität an. 7 BE
- Erläutern Sie zwei Entwurfsentscheidungen Ihres Diagramms: die Modellierung der Elektroautos und die Verbindung zwischen Buchung und Kunde. 4 BE
- Implementieren Sie die Klasse
Buchungmit Konstruktor und der Methodekosten(): Fließkommazahl. Der Konstruktor soll dafür sorgen, dass Anforderung (7) erfüllt bleibt. 5 BE - Stellen Sie den Zustand nach den folgenden Anweisungen als Objektdiagramm dar und geben Sie den Rückgabewert von
b.kosten()an.Kunde k = new Kunde("Jo", "B123"); EAuto e = new EAuto("H-E 42", 0.30, 80); Buchung b = new Buchung(k, e, 45);3 BE
Summe: 19 BE
Hinweise
Hinweis zu Aufgabe a)
Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
Hinweis zu Aufgabe d)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
- - stationen: DynArray<Station>
- - name: Zeichenkette
- - fahrzeuge: Reihung von Fahrzeug
- - kennzeichen: Zeichenkette
- - preisProMinute: Fließkommazahl
- + getPreisProMinute(): Fließkommazahl
- - akkustand: Ganzzahl
- c EAuto(k: Zeichenkette, p: Fließkommazahl, akku: Ganzzahl)
- - name: Zeichenkette
- - fuehrerscheinNr: Zeichenkette
- - buchungen: DynArray<Buchung>
- + hinzufuegen(b: Buchung)
- - minuten: Ganzzahl
- - kunde: Kunde
- - fahrzeug: Fahrzeug
- c Buchung(k: Kunde, f: Fahrzeug, min: Ganzzahl)
- + kosten(): Fließkommazahl
(1) → Anbieter mit * Stationen; (2) „bis zu zehn“ → 0..10, Reihung der Länge 10; (3) Attribute von Fahrzeug; (4) „sind Fahrzeuge“ → EAuto erbt von Fahrzeug; (5) Attribute von Kunde; (6) Buchung → 1 Kunde, → 1 Fahrzeug, Attribut minuten, Methode kosten(); (7) Kunde → * Buchung, also ist die Beziehung Kunde–Buchung in beide Richtungen navigierbar. Bewertet: sechs Klassen (2 BE), Vererbung (1 BE), fünf Assoziationen mit Kardinalitäten und Richtung (3 BE), Attribute/Methoden (1 BE).
Erwartungshorizont zu Aufgabe b)
Elektroautos: Ein Elektroauto ist ein Fahrzeug und hat alle seine Eigenschaften; nur der Akkustand kommt hinzu. Als Unterklasse erbt EAuto Kennzeichen, Preis und getPreisProMinute(); Stationen und Buchungen können mit dem Typ Fahrzeug arbeiten und nehmen trotzdem Elektroautos auf. Ein Attribut akkustand in Fahrzeug wäre bei Verbrennern sinnlos. Buchung und Kunde: Die Buchung speichert eine Referenz auf das Kunden-Objekt statt Name oder Führerscheinnummer — so ist der Kunde eindeutig und direkt erreichbar. Weil (7) verlangt, dass der Kunde seine Buchungen kennt, gibt es zusätzlich die Rückrichtung; beide Seiten müssen gemeinsam gesetzt werden (siehe c).
Erwartungshorizont zu Aufgabe c)
public class Buchung {
private Kunde kunde;
private Fahrzeug fahrzeug;
private int minuten;
public Buchung(Kunde kunde, Fahrzeug fahrzeug, int minuten) {
this.kunde = kunde;
this.fahrzeug = fahrzeug;
this.minuten = minuten;
kunde.hinzufuegen(this); // Kunde kennt seine Buchungen
}
public double kosten() {
return minuten * fahrzeug.getPreisProMinute();
}
}Bewertet: Attribute (1 BE), Konstruktor (1 BE), Eintragen beim Kunden mit this (2 BE), kosten() über die Referenz auf das Fahrzeug (1 BE).
Erwartungshorizont zu Aufgabe d)
- name = "Jo"
- fuehrerscheinNr = "B123"
- buchungen = [b]
- minuten = 45
- kunde → k
- fahrzeug → e
- kennzeichen = "H-E 42"
- preisProMinute = 0.3
- akkustand = 80
Das Elektroauto enthält auch die geerbten Attribute. b.kosten() = 45 · 0,30 = 13,5.
Das Festival
AFB II–IIIFür ein Musikfestival soll eine Planungs- und Ticketsoftware entstehen. Ein Praktikant hat bereits einen ersten Entwurf erstellt.
- - name: Zeichenkette
- - buehnen: DynArray<Buehne>
- - bandnamen: DynArray<Zeichenkette>
- - bandname: Zeichenkette
- - buehnennummer: Ganzzahl
- - beginn: Zeichenkette
- - preis: Fließkommazahl
- - tag: Zeichenkette
- - kaeufer: Zeichenkette
- - preis: Fließkommazahl
- - kaeufer: Zeichenkette
- - nummer: Ganzzahl
- - kapazitaet: Ganzzahl
Anforderungen: Ein Festival hat mehrere Bühnen und viele Auftritte. Jeder Auftritt findet mit genau einer Band auf genau einer Bühne statt; eine Band kann mehrmals auftreten. Tickets gibt es als Tagesticket (für einen Tag) und als Festivalticket; jedes Ticket hat einen Preis und kennt seinen Käufer, eine Person mit Name und E-Mail-Adresse.
- Analysieren Sie den Entwurf. Stellen Sie drei Schwächen heraus und begründen Sie jeweils, welche Probleme sie im Programm verursachen. 5 BE
- Entwerfen Sie einen überarbeiteten Entwurf als Klassendiagramm, der die Schwächen behebt und alle Anforderungen erfüllt. 6 BE
- Implementieren Sie die Methode
auftritteVon(b: Band): Ganzzahlder KlasseFestival, die zählt, wie oft die Bandbauftritt.AuftrittbietetgetBand(): Bandan. 4 BE - Erörtern Sie, ob ein Ticket seinen Käufer als Objekt kennen sollte oder ob umgekehrt eine Person ihre Tickets kennen sollte. 4 BE
Summe: 19 BE
Hinweise
Hinweis zu Aufgabe a)
Hinweis zu Aufgabe b)
Band, Person und eine Oberklasse für die Tickets.Hinweis zu Aufgabe c)
Hinweis zu Aufgabe d)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
(1) Namen statt Referenzen: bandname, buehnennummer, kaeufer sind Zeichenketten bzw. Zahlen. Tippfehler führen zu Bands, die es nicht gibt; ändert eine Band ihren Namen, müssen alle Auftritte geändert werden; weitere Daten der Band sind nicht erreichbar. (2) Doppelte Attribute: preis und kaeufer stehen in beiden Ticketklassen — gemeinsame Methoden müssten doppelt programmiert werden, eine Liste „aller Tickets“ ist nicht möglich. (3) Fehlende Beziehung: Das Festival kennt seine Auftritte nicht, nur eine Liste von Bandnamen; ein Programm kann das Line-up gar nicht durchlaufen. Weitere mögliche Punkte: Käufer als Zeichenkette statt eigener Klasse Person.
Erwartungshorizont zu Aufgabe b)
- - name: Zeichenkette
- - buehnen: DynArray<Buehne>
- - auftritte: DynArray<Auftritt>
- + auftritteVon(b: Band): Ganzzahl
- - beginn: Zeichenkette
- - band: Band
- - buehne: Buehne
- + getBand(): Band
- - name: Zeichenkette
Außerdem: Festival → * Buehne, Auftritt → 1 Buehne.
- - preis: Fließkommazahl
- - kaeufer: Person
- + getPreis(): Fließkommazahl
- - tag: Zeichenkette
- - name: Zeichenkette
- - email: Zeichenkette
Bewertet: Band und Person als Klassen mit Referenzen (2 BE), Oberklasse Ticket mit Vererbung (2 BE), Assoziationen mit Kardinalitäten 1 und * (2 BE).
Erwartungshorizont zu Aufgabe c)
public int auftritteVon(Band b) {
int anzahl = 0;
for (int i = 0; i < auftritte.size(); i++) {
if (auftritte.get(i).getBand() == b) {
anzahl++;
}
}
return anzahl;
}Test: Tritt die Band „Echo“ an zwei von drei geplanten Auftritten auf, liefert die Methode 2. Der Vergleich mit == ist hier richtig, weil es für jede Band genau ein Objekt gibt.
Erwartungshorizont zu Aufgabe d)
Ticket kennt Person: Bei der Einlasskontrolle wird ein Ticket gescannt und der Name des Käufers mit dem Ausweis verglichen — dafür muss man vom Ticket zur Person navigieren. Die Anforderung „kennt seinen Käufer“ verlangt genau diese Richtung. Person kennt Tickets: Sinnvoll für eine Ansicht „Meine Tickets“ oder zum Stornieren, sonst müsste man alle Tickets durchsuchen. Beides zusammen macht die Beziehung bidirektional und erfordert, dass beim Kauf beide Seiten gesetzt werden. Fazit: Pflicht ist die Richtung Ticket → Person; die Gegenrichtung nur, wenn eine Funktion sie wirklich braucht — jede zusätzliche Richtung ist eine Fehlerquelle. Aus Datenschutzsicht spricht für Sparsamkeit zudem, dass eine Person-Klasse mit allen Tickets ein vollständiges Kaufprofil darstellt.
