Assignment Chef icon Assignment Chef
All German tutorials

Programming lesson

Benutzergeschichten in der OOP-Programmierung: Eine Schritt-für-Schritt-Anleitung für CAB201 Assignment 2

Lerne, wie du Benutzergeschichten für eine Liefer-App wie Arriba Eats in C# mit objektorientierter Programmierung umsetzt – inklusive Tutorial für CAB201 Assignment 2.

CAB201 Assignment 2 Benutzergeschichten User Stories objektorientierte Programmierung C# Liefer-App Arriba Eats OOP Tutorial Programmierung lernen C# Konsolenanwendung Klassenmodellierung Authentifizierung Login Logout Bestellstatus Bewertungssystem CAB201 Lösungsansatz Softwareentwicklung Studium

Einführung: Benutzergeschichten und objektorientierte Programmierung

Im Rahmen des CAB201 Assignment 2 geht es darum, eine textbasierte Liefer-App namens Arriba Eats zu entwickeln. Die Grundlage bilden Benutzergeschichten (User Stories), die die Anforderungen aus Sicht der Nutzer beschreiben. Dieses Tutorial zeigt dir, wie du diese Geschichten in C# mit objektorientierter Programmierung (OOP) umsetzt – ganz ohne die fertige Lösung zu verraten. Du wirst lernen, Klassen zu modellieren, Benutzerrollen zu unterscheiden und die Geschäftslogik sauber von der Benutzeroberfläche zu trennen.

Stell dir vor, die App wäre wie eine Lieferplattform, die ähnlich wie aktuelle Trends funktioniert: Kunden bestellen Essen, Restaurants bereiten zu, und Fahrer liefern aus. Genau wie bei Lieferando oder Uber Eats gibt es verschiedene Benutzer mit unterschiedlichen Rechten. In der Programmierung bilden wir das mit Klassen und Vererbung ab.

Grundlagen der Benutzergeschichten

Benutzergeschichten folgen dem Format: „Als ein [Rolle] möchte ich [Funktion], damit [Nutzen].“ Für Arriba Eats gibt es drei Rollen: Kunde, Lieferant und Restaurantbesitzer (Client). Jede Rolle hat spezifische Anforderungen. Die erste Geschichte (User Story 1) lautet zum Beispiel: „Als Benutzer möchte ich mich mit Name, Alter, E-Mail, Handynummer und Passwort registrieren, damit meine Daten geschützt sind.“

In der OOP bedeutet das: Eine Basisklasse User mit gemeinsamen Attributen, und abgeleitete Klassen für jede Rolle. So bleibt der Code wiederverwendbar und erweiterbar.

Schritt 1: Modellierung der Benutzerklassen

Beginne mit einer abstrakten Klasse User:

public abstract class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
    public string Password { get; set; }
}

Dann erstellst du die spezifischen Klassen:

public class Customer : User
{
    public double X { get; set; }
    public double Y { get; set; }
}

public class Deliverer : User
{
    public string LicensePlate { get; set; }
}

public class Client : User
{
    public string RestaurantName { get; set; }
    public string Style { get; set; }
    public double RestaurantX { get; set; }
    public double RestaurantY { get; set; }
}

Diese Struktur erlaubt es, später weitere Attribute hinzuzufügen, ohne bestehenden Code zu ändern – ein Prinzip namens Offen/geschlossen-Prinzip.

Schritt 2: Authentifizierung und Sitzungsverwaltung

Die Benutzergeschichten 2 bis 4 drehen sich um Login, Profilanzeige und Logout. Implementiere eine Klasse AuthManager, die eine Liste registrierter Benutzer verwaltet und den aktuell eingeloggten Benutzer speichert. Verwende Dependency Injection, um die Abhängigkeit von der Benutzeroberfläche zu trennen. So bleibt die Geschäftslogik testbar und unabhängig von der Konsolenein-/ausgabe.

Ein einfaches Beispiel:

public class AuthManager
{
    private List<User> users = new List<User>();
    public User CurrentUser { get; private set; }

    public bool Register(User user)
    {
        // Prüfen, ob E-Mail bereits existiert
        if (users.Any(u => u.Email == user.Email))
            return false;
        users.Add(user);
        return true;
    }

    public bool Login(string email, string password)
    {
        var user = users.FirstOrDefault(u => u.Email == email && u.Password == password);
        if (user != null)
        {
            CurrentUser = user;
            return true;
        }
        return false;
    }

    public void Logout()
    {
        CurrentUser = null;
    }
}

Schritt 3: Trennung von UI und Geschäftslogik

Die Aufgabenstellung betont, dass die Benutzeroberfläche (UI) von der Anwendungslogik getrennt sein muss. Erstelle daher eigene Klassen für die Menüführung, z. B. ConsoleUI, die nur für Ein-/Ausgabe zuständig ist. Die Geschäftslogik liegt in Service-Klassen wie UserService oder OrderService. Dies entspricht dem Model-View-Controller (MVC)-Muster und erleichtert später die Umstellung auf eine grafische Oberfläche.

Schritt 4: Restaurant- und Menüverwaltung (User Stories 7–9)

Als Restaurantbesitzer kannst du dein Restaurant mit Name, Stil (z. B. Italienisch, Chinesisch) und Standort registrieren. Modelliere eine Klasse Restaurant mit Attributen und einer Liste von MenuItem-Objekten. Jedes Menüelement hat einen Namen und einen Preis. Der Client kann seine eigenen Restaurantdaten einsehen und Menüpunkte hinzufügen. Verwende Listen und LINQ, um Abfragen wie „Alle Restaurants eines Clients“ zu ermöglichen.

Schritt 5: Bestellprozess und Statusverwaltung (User Stories 14–29)

Der Bestellablauf ist das Herzstück der App. Ein Kunde wählt ein Restaurant aus, sieht die Speisekarte, bestellt Artikel mit Mengen. Die Bestellung durchläuft Status: bestellt → kochen → gekocht → wird geliefert → geliefert. Modelliere eine Order-Klasse mit Status als Enum:

public enum OrderStatus { Ordered, Cooking, Cooked, BeingDelivered, Delivered }

public class Order
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
    public Client Client { get; set; }
    public Deliverer Deliverer { get; set; }
    public List<OrderItem> Items { get; set; }
    public OrderStatus Status { get; set; }
    public double TotalPrice { get; set; }
}

Der Client kann den Status von „bestellt“ auf „kochen“ ändern, der Lieferant nach Ankunft auf „wird geliefert“ usw. Diese Statusänderungen sind typische Zustandsübergänge, die du mit einer Zustandsmaschine abbilden kannst.

Schritt 6: Bewertungen und Statistiken (User Stories 30–31)

Nach der Lieferung kann der Kunde das Restaurant mit einer Sternebewertung (1–5) und einem Kommentar bewerten. Die Bewertungen fließen in die durchschnittliche Bewertung des Restaurants ein. Der Kunde sieht außerdem seine eigene Bestellhistorie und die Gesamtausgaben. Dies erfordert eine Verknüpfung zwischen Bestellungen und Bewertungen sowie Aggregatfunktionen wie Sum() und Average().

Praktische Tipps für die Umsetzung

  • Iterativ vorgehen: Beginne mit einer Benutzergeschichte und erweitere schrittweise. So vermeidest du Überladung.
  • Testen mit Konsolenausgabe: Da die UI textbasiert ist, achte auf exakte Formatierung – Gradescope vergleicht die Ausgabe zeichengenau.
  • Daten im Speicher: Verwende List<T> oder Dictionary für die Speicherung, da keine Datenbank verwendet wird.
  • Vererbung und Polymorphie nutzen: Gemeinsame Eigenschaften der Benutzer in der Basisklasse reduzieren Code-Duplikation.
  • Trends einbinden: Denke an aktuelle Lieferdienste – die App ähnelt stark Wolt oder Glovo. Solche Vergleiche helfen, das Design zu verstehen.

Häufige Fehler vermeiden

  • UI und Logik vermischen: Schreibe keine Console.WriteLine in Service-Klassen. Verwende Rückgabewerte und überlasse die Ausgabe der UI-Klasse.
  • Zu viel auf einmal: Konzentriere dich auf eine User Story pro Schritt. Nutze Inkrementelle Entwicklung.
  • Falsche Rollenidentifikation: Achte darauf, dass nur Clients Restaurants registrieren können, nur Kunden bestellen usw.
  • Vergessen der Standortberechnung: Die Entfernung zwischen Lieferant, Restaurant und Kunde muss berechnet werden – verwende den euklidischen Abstand.

Fazit

Mit diesem Tutorial hast du einen Fahrplan, um die Benutzergeschichten des CAB201 Assignment 2 strukturiert und objektorientiert umzusetzen. Die Trennung von UI und Logik, die Modellierung der Rollen und die schrittweise Implementierung sind der Schlüssel zum Erfolg. Viel Erfolg bei deinem Projekt!