Service de location de véhicules
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy. Leçon 70 sur 70.
Défi
FacileConstruisons un service de location de véhicules qui réunit l’héritage, les interfaces et le modèle Strategy ! Vous allez créer un système dans lequel différents types de véhicules peuvent être loués à l’aide de stratégies de tarification flexibles, démontrant ainsi comment la POO permet de gérer une logique métier maintenable et extensible.
Vous organiserez votre code sur six fichiers :
Vehicle.cs: créez votre hiérarchie de véhicules dans l’espace de nomsRental.Models. La classe de baseVehicledoit posséder les propriétés en lecture seuleLicensePlateetBrand, uneDailyRate(décimale), ainsi qu’une propriétéIsAvailableavec un setter privé contrôlé par les méthodesMarkAsRented()etMarkAsReturned(). Créez ensuite trois classes dérivées :Caravec une propriétéSeats,Motorcycleavec une propriétéEngineCC, etTruckavec une propriétéCargoCapacity(décimale). Chaque classe dérivée doit appeler le constructeur de base et définir sa propriété spécifique.IPricingStrategy.cs: définissez l’interfaceIPricingStrategydans l’espace de nomsRental.Pricing, avec une seule méthodeCalculatePrice(Vehicle vehicle, int days)qui renvoie une valeur décimale.PricingStrategies.cs: implémentez deux stratégies de tarification dans l’espace de nomsRental.Pricing.StandardPricingmultiplie simplement le tarif journalier du véhicule par le nombre de jours.WeekendDiscountPricingapplique une remise de 10 % (multiplication par 0.9) si la location dure 2 jours ou plus ; sinon, elle utilise le calcul standard.RentalRecord.cs: créez une classeRentaldans l’espace de nomsRental.Modelspour suivre les locations. Elle doit avoir des propriétés en lecture seule pourCustomerName(chaîne),Vehicle(Vehicle),Days(entier) etTotalPrice(décimale), toutes définies par l’intermédiaire du constructeur.RentalService.cs: créez une classeRentalServicedans l’espace de nomsRental.Servicesqui gère le parc de véhicules et traite les locations. Elle reçoit uneIPricingStrategypar l’intermédiaire de son constructeur (injection de dépendances). Implémentez :AddVehicle(Vehicle vehicle)- ajoute un véhicule au parcRentVehicle(string customerName, string licensePlate, int days)- renvoie un objetRentalsi le véhicule existe et est disponible ; sinon, renvoienull. N’oubliez pas de marquer le véhicule comme loué et de calculer le prix à l’aide de la stratégie injectée.ReturnVehicle(string licensePlate)- marque le véhicule comme disponible et renvoietrueen cas de réussiteGetAvailableVehicles()- renvoie une liste de tous les véhicules disponibles
Program.cs: assemblez tous les éléments en créant des véhicules, en configurant le service avec une stratégie de tarification et en traitant les opérations de location en fonction des entrées.
Vous recevrez les entrées suivantes :
- Stratégie de tarification à utiliser (
standardouweekend) - Nombre de véhicules à ajouter
- Pour chaque véhicule : type (
car,motorcycleoutruck), plaque d’immatriculation, marque, tarif journalier et valeur spécifique au type (nombre de sièges, engineCC ou capacité de chargement) - Nombre d’opérations à effectuer
- Pour chaque opération : l’action suivie des données pertinentes
Formats des opérations :
rent
{customerName}
{licensePlate}
{days}
return
{licensePlate}
availableFormats de sortie :
- Location réussie :
Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice} - Échec de la location :
Rental failed: {licensePlate} - Retour réussi :
Returned: {licensePlate} - Échec du retour :
Return failed: {licensePlate} - Véhicules disponibles : affichez chaque véhicule disponible sous la forme
{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day, où Type vaut "Car", "Motorcycle" ou "Truck"
Par exemple, si les entrées sont :
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-123La sortie devrait être :
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-123Remarquez comment la stratégie de tarification est injectée dans le service : vous pourriez facilement remplacer StandardPricing par WeekendDiscountPricing sans modifier le code de RentalService. C’est toute la puissance du modèle Strategy combiné à l’injection de dépendances !
Essayez vous-même
using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;
class Program
{
public static void Main(string[] args)
{
// Lire le type de stratégie de tarification
string strategyType = Console.ReadLine();
// TODO: Créer la stratégie de tarification appropriée en fonction de l'entrée
// "standard" -> StandardPricing
// "weekend" -> WeekendDiscountPricing
IPricingStrategy strategy = null; // TODO: Initialiser en fonction de strategyType
// TODO: Créer RentalService avec la stratégie de tarification
// Lire le nombre de véhicules
int vehicleCount = Convert.ToInt32(Console.ReadLine());
// TODO: Lire et ajouter chaque véhicule au service
// Pour chaque véhicule, lire :
// - type (car, motorcycle, truck)
// - license plate
// - brand
// - tarif journalier
// - valeur spécifique au type (seats, engineCC, ou cargo capacity)
// Lire le nombre d'opérations
int operationCount = Convert.ToInt32(Console.ReadLine());
// TODO: Traiter chaque opération
// Opérations : rent, return, available
//
// Pour "rent" :
// Lire customerName, licensePlate, days
// Sortie : "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
// Ou : "Rental failed: {licensePlate}"
//
// Pour "return" :
// Lire licensePlate
// Sortie : "Returned: {licensePlate}" ou "Return failed: {licensePlate}"
//
// Pour "available" :
// Afficher chaque véhicule disponible comme suit :
// "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
}
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et UtilisateurLogique du système d'empruntLINQ pour la rechercheInterface Console / Interface d'administrationTests unitaires (NUnit/xUnit)Entraînez-vous par vous-même : Compilateur C# en ligne