Fahrzeugvermietungsdienst
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 70 von 70.
Aufgabe
EinfachLass 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 NamespaceRental.Models. Die BasisklasseVehiclesollte schreibgeschützte EigenschaftenLicensePlateundBrand, eine EigenschaftDailyRate(decimal) sowie eine EigenschaftIsAvailablemit einem privaten Setter besitzen, der durch die MethodenMarkAsRented()undMarkAsReturned()gesteuert wird. Erstelle anschließend drei abgeleitete Klassen:Carmit einer EigenschaftSeats,Motorcyclemit einer EigenschaftEngineCCundTruckmit einer EigenschaftCargoCapacity(decimal). Jede abgeleitete Klasse sollte den Basiskonstruktor aufrufen und ihre jeweils eigene Eigenschaft festlegen.IPricingStrategy.cs: Definiere die SchnittstelleIPricingStrategyim NamespaceRental.Pricingmit einer einzigen MethodeCalculatePrice(Vehicle vehicle, int days), die einen Dezimalwert zurückgibt.PricingStrategies.cs: Implementiere zwei Preisstrategien im NamespaceRental.Pricing.StandardPricingmultipliziert einfach den Tagessatz des Fahrzeugs mit der Anzahl der Tage.WeekendDiscountPricinggewä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 KlasseRentalim NamespaceRental.Models, um Vermietungen zu verfolgen. Sie sollte schreibgeschützte Eigenschaften fürCustomerName(string),Vehicle(Vehicle),Days(int) undTotalPrice(decimal) besitzen, die alle über den Konstruktor festgelegt werden.RentalService.cs: Erstelle eine KlasseRentalServiceim NamespaceRental.Services, die den Fuhrpark verwaltet und Vermietungen verarbeitet. Sie erhält eineIPricingStrategyüber ihren Konstruktor (Dependency Injection). Implementiere:AddVehicle(Vehicle vehicle)– fügt ein Fahrzeug zum Fuhrpark hinzuRentVehicle(string customerName, string licensePlate, int days)– gibt einRental-Objekt zurück, wenn das Fahrzeug existiert und verfügbar ist, andernfallsnull. 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 ErfolgtruezurückGetAvailableVehicles()– 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 (
standardoderweekend) - Anzahl der hinzuzufügenden Fahrzeuge
- Für jedes Fahrzeug: Typ (
car,motorcycleodertruck), 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}
availableAusgabeformate:
- 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}/dayaus, 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-123Die 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-123Beachte, 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
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjektinitialisiererWiederholung – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbungs-(:)-SyntaxDas „base“-Schlüsselwort„virtual“- und „override“-SchlüsselwörterVersiegelte KlassenDie „object“-BasisklasseWiederholung – Mitarbeiterhierarchie7Erweiterte Funktionen
Überladen von OperatorenIndexer (this[])ToString()-ÜberschreibungErweiterungsmethodenRückblick – Benutzerdefinierte Liste10Entwurfsmuster Teil 1
Einführung in EntwurfsmusterThread-sicheres SingletonFactory-MusterObserver-Muster (Events)Strategy-Muster13Abschließende Herausforderungen
E-Learning-PlattformKomponente für SpielfigurenFahrzeugvermietungsdienst2Eigenschaften & statische Member
Automatisch implementierte EigenschaftenNur lesbare/schreibbare EigenschaftenStatische Felder & MethodenStatische KlassenMember mit Ausdruckskörpern5Polymorphie & Interfaces
Compile- vs. Laufzeit-PolymorphieInterface vs. abstrakte KlasseMehrere InterfacesExplizite InterfacesUpcasting & DowncastingWiederholung – Formenrechner3Klassenarchitektur
Instanz- vs. statische DatenSchlüsselwörter 'readonly' & 'const'Backing FieldsRückblick – Bankkontenverwaltung6Kapselung
ZugriffsmodifikatorenEigenschaften zur KapselungImplementierung der DatenkapselungMuster für UnveränderlichkeitRückblick – SchülerdatenÜbe selbstständig: Online-C#-Compiler