Menu
Coddy logo textTech

Fahrzeugvermietungsdienst

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 70 von 70.

challenge icon

Aufgabe

Einfach

Lass uns einen Fahrzeugvermietungsdienst erstellen, der Vererbung, Schnittstellen und das Strategy-Muster miteinander verbindet! Du erstellst ein System, in dem verschiedene Fahrzeugtypen mithilfe flexibler Preisstrategien vermietet werden können – und demonstrierst damit, wie OOP wartbare und erweiterbare Geschäftslogik ermöglicht.

Du organisierst deinen Code auf sechs Dateien verteilt:

  • Vehicle.cs: Erstelle deine Fahrzeughierarchie im Namespace Rental.Models. Die Basisklasse Vehicle sollte schreibgeschützte Eigenschaften LicensePlate und Brand, eine Eigenschaft DailyRate (decimal) sowie eine Eigenschaft IsAvailable mit einem privaten Setter besitzen, der durch die Methoden MarkAsRented() und MarkAsReturned() gesteuert wird. Erstelle anschließend drei abgeleitete Klassen: Car mit einer Eigenschaft Seats, Motorcycle mit einer Eigenschaft EngineCC und Truck mit einer Eigenschaft CargoCapacity (decimal). Jede abgeleitete Klasse sollte den Basiskonstruktor aufrufen und ihre jeweils eigene Eigenschaft festlegen.
  • IPricingStrategy.cs: Definiere die Schnittstelle IPricingStrategy im Namespace Rental.Pricing mit einer einzigen Methode CalculatePrice(Vehicle vehicle, int days), die einen Dezimalwert zurückgibt.
  • PricingStrategies.cs: Implementiere zwei Preisstrategien im Namespace Rental.Pricing. StandardPricing multipliziert einfach den Tagessatz des Fahrzeugs mit der Anzahl der Tage. WeekendDiscountPricing gewährt einen Rabatt von 10 % (Multiplikation mit 0.9), wenn das Fahrzeug für mindestens 2 Tage gemietet wird, und verwendet andernfalls die Standardberechnung.
  • RentalRecord.cs: Erstelle eine Klasse Rental im Namespace Rental.Models, um Vermietungen zu verfolgen. Sie sollte schreibgeschützte Eigenschaften für CustomerName (string), Vehicle (Vehicle), Days (int) und TotalPrice (decimal) besitzen, die alle über den Konstruktor festgelegt werden.
  • RentalService.cs: Erstelle eine Klasse RentalService im Namespace Rental.Services, die den Fuhrpark verwaltet und Vermietungen verarbeitet. Sie erhält eine IPricingStrategy über ihren Konstruktor (Dependency Injection). Implementiere:
    • AddVehicle(Vehicle vehicle) – fügt ein Fahrzeug zum Fuhrpark hinzu
    • RentVehicle(string customerName, string licensePlate, int days) – gibt ein Rental-Objekt zurück, wenn das Fahrzeug existiert und verfügbar ist, andernfalls null. Denke daran, das Fahrzeug als vermietet zu markieren und den Preis mithilfe der injizierten Strategie zu berechnen.
    • ReturnVehicle(string licensePlate) – markiert das Fahrzeug als verfügbar und gibt bei Erfolg true zurück
    • GetAvailableVehicles() – gibt eine Liste aller verfügbaren Fahrzeuge zurück
  • Program.cs: Führe alles zusammen, indem du Fahrzeuge erstellst, den Dienst mit einer Preisstrategie einrichtest und Vermietungsvorgänge auf Grundlage der Eingaben verarbeitest.

Du erhältst die folgenden Eingaben:

  • Zu verwendende Preisstrategie (standard oder weekend)
  • Anzahl der hinzuzufügenden Fahrzeuge
  • Für jedes Fahrzeug: Typ (car, motorcycle oder truck), Kennzeichen, Marke, Tagessatz und typspezifischer Wert (Sitze, engineCC oder Ladekapazität)
  • Anzahl der auszuführenden Vorgänge
  • Für jeden Vorgang: die Aktion, gefolgt von den relevanten Daten

Formate der Vorgänge:

rent
{customerName}
{licensePlate}
{days}

return
{licensePlate}

available

Ausgabeformate:

  • Erfolgreiche Vermietung: Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}
  • Fehlgeschlagene Vermietung: Rental failed: {licensePlate}
  • Erfolgreiche Rückgabe: Returned: {licensePlate}
  • Fehlgeschlagene Rückgabe: Return failed: {licensePlate}
  • Verfügbare Fahrzeuge: Gib jedes verfügbare Fahrzeug als {Type}: {Brand} ({LicensePlate}) - {DailyRate}/day aus, wobei Type entweder "Car", "Motorcycle" oder "Truck" ist

Wenn die Eingaben beispielsweise wie folgt aussehen:

weekend
3
car
ABC-123
Toyota
50
5
motorcycle
XYZ-789
Honda
30
600
truck
TRK-001
Ford
80
2000
5
available
rent
Alice
ABC-123
3
rent
Bob
ABC-123
2
available
return
ABC-123

Die Ausgabe sollte wie folgt aussehen:

Car: Toyota (ABC-123) - 50/day
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Rented: Toyota (ABC-123) to Alice for 3 days - Total: 135.0
Rental failed: ABC-123
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Returned: ABC-123

Beachte, wie die Preisstrategie in den Dienst injiziert wird – du könntest StandardPricing problemlos durch WeekendDiscountPricing ersetzen, ohne den Code von RentalService überhaupt zu ändern. Das ist die Stärke des Strategy-Musters in Kombination mit Dependency Injection!

Probier es selbst

using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;

class Program
{
    public static void Main(string[] args)
    {
        // Preistyp der Strategie lesen
        string strategyType = Console.ReadLine();
        
        // TODO: Erstelle die passende Preisstrategie basierend auf der Eingabe
        // "standard" -> StandardPricing
        // "weekend" -> WeekendDiscountPricing
        IPricingStrategy strategy = null; // TODO: Basierend auf strategyType initialisieren
        
        // TODO: RentalService mit der Preisstrategie erstellen
        
        // Anzahl der Fahrzeuge lesen
        int vehicleCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Jedes Fahrzeug lesen und zum Service hinzufügen
        // Für jedes Fahrzeug lesen:
        // - Typ (car, motorcycle, truck)
        // - Kennzeichen
        // - Marke
        // - Tagesrate
        // - typspezifischer Wert (seats, engineCC oder cargo capacity)
        
        // Anzahl der Operationen lesen
        int operationCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Jede Operation verarbeiten
        // Operationen: rent, return, available
        // 
        // Für "rent":
        //   customerName, licensePlate, days lesen
        //   Ausgabe: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
        //   Oder: "Rental failed: {licensePlate}"
        //
        // Für "return":
        //   licensePlate lesen
        //   Ausgabe: "Returned: {licensePlate}" oder "Return failed: {licensePlate}"
        //
        // Für "available":
        //   Gib jedes verfügbare Fahrzeug wie folgt aus:
        //   "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
    }
}

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C#-Compiler