Menu
Coddy logo textTech

Usługa wynajmu pojazdów

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 70 z 70.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system wypożyczania pojazdów, który łączy dziedziczenie, interfejsy i wzorzec Strategia! Stworzysz system, w którym można wypożyczać różne typy pojazdów, korzystając z elastycznych strategii cenowych — pokażemy, jak OOP umożliwia tworzenie łatwej w utrzymaniu i rozszerzaniu logiki biznesowej.

Rozmieścisz kod w sześciu plikach:

  • Vehicle.cs: Utwórz hierarchię pojazdów w przestrzeni nazw Rental.Models. Bazowa klasa Vehicle powinna mieć tylko do odczytu właściwości LicensePlate i Brand, właściwość DailyRate (decimal) oraz właściwość IsAvailable z prywatnym setterem, której stan zmienia się za pomocą metod MarkAsRented() i MarkAsReturned(). Następnie utwórz trzy klasy pochodne: Car z właściwością Seats, Motorcycle z właściwością EngineCC oraz Truck z właściwością CargoCapacity (decimal). Każda klasa pochodna powinna wywoływać konstruktor klasy bazowej i ustawiać swoją unikatową właściwość.
  • IPricingStrategy.cs: Zdefiniuj interfejs IPricingStrategy w przestrzeni nazw Rental.Pricing z jedną metodą CalculatePrice(Vehicle vehicle, int days), która zwraca wartość typu decimal.
  • PricingStrategies.cs: Zaimplementuj dwie strategie cenowe w przestrzeni nazw Rental.Pricing. StandardPricing po prostu mnoży dzienną stawkę za pojazd przez liczbę dni. WeekendDiscountPricing udziela 10% zniżki (mnoży przez 0.9), jeśli wypożyczenie trwa 2 dni lub dłużej; w przeciwnym razie stosuje standardowe obliczenie.
  • RentalRecord.cs: Utwórz klasę Rental w przestrzeni nazw Rental.Models, która będzie przechowywać informacje o wypożyczeniach. Powinna mieć tylko do odczytu właściwości CustomerName (string), Vehicle (Vehicle), Days (int) i TotalPrice (decimal), ustawiane za pomocą konstruktora.
  • RentalService.cs: Utwórz klasę RentalService w przestrzeni nazw Rental.Services, która zarządza flotą i obsługuje wypożyczenia. Otrzymuje IPricingStrategy za pośrednictwem konstruktora (wstrzykiwanie zależności). Zaimplementuj:
    • AddVehicle(Vehicle vehicle) — dodaje pojazd do floty
    • RentVehicle(string customerName, string licensePlate, int days) — zwraca obiekt Rental, jeśli pojazd istnieje i jest dostępny; w przeciwnym razie zwraca null. Pamiętaj, aby oznaczyć pojazd jako wypożyczony i obliczyć cenę przy użyciu wstrzykniętej strategii.
    • ReturnVehicle(string licensePlate) — oznacza pojazd jako dostępny i zwraca true, jeśli operacja się powiedzie
    • GetAvailableVehicles() — zwraca listę wszystkich dostępnych pojazdów
  • Program.cs: Połącz wszystkie elementy, tworząc pojazdy, konfigurując usługę ze strategią cenową i obsługując operacje wypożyczania na podstawie danych wejściowych.

Otrzymasz następujące dane wejściowe:

  • Strategię cenową do zastosowania (standard lub weekend)
  • Liczbę pojazdów do dodania
  • Dla każdego pojazdu: typ (car, motorcycle lub truck), numer rejestracyjny, markę, stawkę dzienną i wartość charakterystyczną dla danego typu (liczbę miejsc, engineCC lub ładowność)
  • Liczbę operacji do wykonania
  • Dla każdej operacji: działanie, a następnie odpowiednie dane

Formaty operacji:

rent
{customerName}
{licensePlate}
{days}

return
{licensePlate}

available

Formaty wyników:

  • Udane wypożyczenie: Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}
  • Nieudane wypożyczenie: Rental failed: {licensePlate}
  • Udany zwrot: Returned: {licensePlate}
  • Nieudany zwrot: Return failed: {licensePlate}
  • Dostępne pojazdy: Wypisz każdy dostępny pojazd w formacie {Type}: {Brand} ({LicensePlate}) - {DailyRate}/day, gdzie Type to "Car", "Motorcycle" lub "Truck"

Na przykład dla następujących danych wejściowych:

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

Wynik powinien być następujący:

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

Zwróć uwagę, jak strategia cenowa jest wstrzykiwana do usługi — możesz łatwo zamienić StandardPricing na WeekendDiscountPricing, nie zmieniając ani trochę kodu RentalService. Na tym polega siła wzorca Strategia w połączeniu z wstrzykiwaniem zależności!

Spróbuj swoich sił

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

class Program
{
    public static void Main(string[] args)
    {
        // Wczytaj typ strategii ustalania cen
        string strategyType = Console.ReadLine();
        
        // TODO: Utwórz odpowiednią strategię ustalania cen na podstawie danych wejściowych
        // "standard" -> StandardPricing
        // "weekend" -> WeekendDiscountPricing
        IPricingStrategy strategy = null; // TODO: Zainicjalizuj na podstawie strategyType
        
        // TODO: Utwórz RentalService ze strategią ustalania cen
        
        // Wczytaj liczbę pojazdów
        int vehicleCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Wczytaj każdy pojazd i dodaj go do usługi
        // Dla każdego pojazdu wczytaj:
        // - typ (samochód, motocykl, ciężarówka)
        // - numer rejestracyjny
        // - marka
        // - stawka dzienna
        // - wartość zależna od typu pojazdu (liczba miejsc, engineCC lub ładowność)
        
        // Wczytaj liczbę operacji
        int operationCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Przetwórz każdą operację
        // Operacje: rent, return, available
        // 
        // Dla "rent":
        //   Wczytaj customerName, licensePlate, days
        //   Wypisz: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
        //   Lub: "Rental failed: {licensePlate}"
        //
        // Dla "return":
        //   Wczytaj licensePlate
        //   Wypisz: "Returned: {licensePlate}" lub "Return failed: {licensePlate}"
        //
        // Dla "available":
        //   Wyświetl każdy dostępny pojazd w formacie:
        //   "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
    }
}

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online