Menu
Coddy logo textTech

Servizio di noleggio veicoli

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 70 di 70.

challenge icon

Sfida

Facile

Costruiamo un servizio di noleggio veicoli che combina ereditarietà, interfacce e pattern Strategy! Creerai un sistema in cui è possibile noleggiare diversi tipi di veicoli usando strategie di prezzo flessibili, dimostrando come la programmazione orientata agli oggetti consenta di realizzare logiche di business manutenibili ed estensibili.

Organizzerai il codice in sei file:

  • Vehicle.cs: crea la gerarchia dei veicoli nello spazio dei nomi Rental.Models. La classe base Vehicle deve avere le proprietà di sola lettura LicensePlate e Brand, una proprietà DailyRate (decimal) e una proprietà IsAvailable con setter privato, controllata tramite i metodi MarkAsRented() e MarkAsReturned(). Crea poi tre classi derivate: Car con una proprietà Seats, Motorcycle con una proprietà EngineCC e Truck con una proprietà CargoCapacity (decimal). Ogni classe derivata deve chiamare il costruttore della classe base e impostare la propria proprietà specifica.
  • IPricingStrategy.cs: definisci l'interfaccia IPricingStrategy nello spazio dei nomi Rental.Pricing con un solo metodo, CalculatePrice(Vehicle vehicle, int days), che restituisce un decimal.
  • PricingStrategies.cs: implementa due strategie di prezzo nello spazio dei nomi Rental.Pricing. StandardPricing moltiplica semplicemente la tariffa giornaliera del veicolo per il numero di giorni. WeekendDiscountPricing applica uno sconto del 10% (moltiplica per 0.9) se il noleggio dura 2 o più giorni; altrimenti usa il calcolo standard.
  • RentalRecord.cs: crea una classe Rental nello spazio dei nomi Rental.Models per tenere traccia dei noleggi. Deve avere le proprietà di sola lettura CustomerName (string), Vehicle (Vehicle), Days (int) e TotalPrice (decimal), tutte impostate tramite il costruttore.
  • RentalService.cs: crea una classe RentalService nello spazio dei nomi Rental.Services che gestisca il parco veicoli ed elabori i noleggi. Riceve un'istanza di IPricingStrategy tramite il costruttore (iniezione delle dipendenze). Implementa:
    • AddVehicle(Vehicle vehicle) - aggiunge un veicolo al parco
    • RentVehicle(string customerName, string licensePlate, int days) - restituisce un oggetto Rental se il veicolo esiste ed è disponibile; altrimenti restituisce null. Ricordati di contrassegnare il veicolo come noleggiato e di calcolare il prezzo usando la strategia iniettata.
    • ReturnVehicle(string licensePlate) - contrassegna il veicolo come disponibile e restituisce true se l'operazione riesce
    • GetAvailableVehicles() - restituisce un elenco di tutti i veicoli disponibili
  • Program.cs: unisci tutti gli elementi creando i veicoli, configurando il servizio con una strategia di prezzo ed elaborando le operazioni di noleggio in base all'input.

Riceverai i seguenti input:

  • Strategia di prezzo da usare (standard o weekend)
  • Numero di veicoli da aggiungere
  • Per ogni veicolo: tipo (car, motorcycle o truck), targa, marca, tariffa giornaliera e valore specifico del tipo (posti, engineCC o capacità di carico)
  • Numero di operazioni da eseguire
  • Per ogni operazione: l'azione seguita dai dati pertinenti

Formati delle operazioni:

rent
{customerName}
{licensePlate}
{days}

return
{licensePlate}

available

Formati dell'output:

  • Noleggio riuscito: Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}
  • Noleggio non riuscito: Rental failed: {licensePlate}
  • Restituzione riuscita: Returned: {licensePlate}
  • Restituzione non riuscita: Return failed: {licensePlate}
  • Veicoli disponibili: stampa ogni veicolo disponibile nel formato {Type}: {Brand} ({LicensePlate}) - {DailyRate}/day, dove Type è "Car", "Motorcycle" o "Truck"

Per esempio, se gli input sono:

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

L'output dovrebbe essere:

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

Nota come la strategia di prezzo venga iniettata nel servizio: potresti sostituire facilmente StandardPricing con WeekendDiscountPricing senza modificare affatto il codice di RentalService. Questa è la potenza del pattern Strategy combinato con l'iniezione delle dipendenze!

Provalo tu

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

class Program
{
    public static void Main(string[] args)
    {
        // Leggi il tipo di strategia di prezzo
        string strategyType = Console.ReadLine();
        
        // TODO: Crea la strategia di prezzo appropriata in base all'input
        // "standard" -> StandardPricing
        // "weekend" -> WeekendDiscountPricing
        IPricingStrategy strategy = null; // TODO: Inizializza in base a strategyType
        
        // TODO: Crea RentalService con la strategia di prezzo
        
        // Leggi il numero di veicoli
        int vehicleCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Leggi e aggiungi ogni veicolo al servizio
        // Per ogni veicolo, leggi:
        // - tipo (car, motorcycle, truck)
        // - targa
        // - marca
        // - tariffa giornaliera
        // - valore specifico del tipo (posti, engineCC o capacità di carico)
        
        // Leggi il numero di operazioni
        int operationCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Elabora ogni operazione
        // Operazioni: rent, return, available
        // 
        // Per "rent":
        //   Leggi customerName, licensePlate, days
        //   Output: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
        //   Oppure: "Rental failed: {licensePlate}"
        //
        // Per "return":
        //   Leggi licensePlate
        //   Output: "Returned: {licensePlate}" oppure "Return failed: {licensePlate}"
        //
        // Per "available":
        //   Visualizza ogni veicolo disponibile nel seguente formato:
        //   "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
    }
}

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C# online