Servicio de alquiler de vehículos
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 70 de 70.
Desafío
Fácil¡Construyamos un servicio de alquiler de vehículos que reúna la herencia, las interfaces y el patrón Strategy! Crearás un sistema en el que se puedan alquilar distintos tipos de vehículos mediante estrategias de precios flexibles, demostrando cómo la POO permite una lógica empresarial mantenible y extensible.
Organizarás tu código en seis archivos:
Vehicle.cs: Crea tu jerarquía de vehículos en el espacio de nombresRental.Models. La clase baseVehicledebe tener propiedades de solo lecturaLicensePlateyBrand, una propiedadDailyRate(decimal) y una propiedadIsAvailablecon un setter privado controlado mediante los métodosMarkAsRented()yMarkAsReturned(). Después, crea tres clases derivadas:Carcon una propiedadSeats,Motorcyclecon una propiedadEngineCCyTruckcon una propiedadCargoCapacity(decimal). Cada clase derivada debe llamar al constructor base y establecer su propiedad única.IPricingStrategy.cs: Define la interfazIPricingStrategyen el espacio de nombresRental.Pricingcon un único métodoCalculatePrice(Vehicle vehicle, int days)que devuelve un decimal.PricingStrategies.cs: Implementa dos estrategias de precios en el espacio de nombresRental.Pricing.StandardPricingsimplemente multiplica la tarifa diaria del vehículo por el número de días.WeekendDiscountPricingaplica un descuento del 10 % (multiplica por 0.9) si el alquiler es de 2 días o más; de lo contrario, utiliza el cálculo estándar.RentalRecord.cs: Crea una claseRentalen el espacio de nombresRental.Modelspara realizar el seguimiento de los alquileres. Debe tener propiedades de solo lectura paraCustomerName(string),Vehicle(Vehicle),Days(int) yTotalPrice(decimal), todas establecidas mediante el constructor.RentalService.cs: Crea una claseRentalServiceen el espacio de nombresRental.Servicesque administre la flota y procese los alquileres. Recibe unIPricingStrategymediante su constructor (inyección de dependencias). Implementa:AddVehicle(Vehicle vehicle): añade un vehículo a la flotaRentVehicle(string customerName, string licensePlate, int days): devuelve un objetoRentalsi el vehículo existe y está disponible; de lo contrario, devuelvenull. Recuerda marcar el vehículo como alquilado y calcular el precio utilizando la estrategia inyectada.ReturnVehicle(string licensePlate): marca el vehículo como disponible y devuelvetruesi la operación se realiza correctamenteGetAvailableVehicles(): devuelve una lista de todos los vehículos disponibles
Program.cs: Integra todo creando vehículos, configurando el servicio con una estrategia de precios y procesando las operaciones de alquiler basadas en la entrada.
Recibirás las siguientes entradas:
- Estrategia de precios que se utilizará (
standardoweekend) - Número de vehículos que se añadirán
- Para cada vehículo: tipo (
car,motorcycleotruck), matrícula, marca, tarifa diaria y valor específico del tipo (asientos, engineCC o capacidad de carga) - Número de operaciones que se realizarán
- Para cada operación: la acción seguida de los datos relevantes
Formatos de las operaciones:
rent
{customerName}
{licensePlate}
{days}
return
{licensePlate}
availableFormatos de salida:
- Alquiler exitoso:
Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice} - Alquiler fallido:
Rental failed: {licensePlate} - Devolución exitosa:
Returned: {licensePlate} - Devolución fallida:
Return failed: {licensePlate} - Disponibles: imprime cada vehículo disponible como
{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day, donde Type es "Car", "Motorcycle" o "Truck"
Por ejemplo, si las entradas son:
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 salida debe ser:
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-123Observa cómo la estrategia de precios se inyecta en el servicio: podrías cambiar fácilmente StandardPricing por WeekendDiscountPricing sin modificar en absoluto el código de RentalService. ¡Este es el poder del patrón Strategy combinado con la inyección de dependencias!
Pruébalo tú mismo
using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;
class Program
{
public static void Main(string[] args)
{
// Leer el tipo de estrategia de precios
string strategyType = Console.ReadLine();
// TODO: Crear la estrategia de precios adecuada basada en la entrada
// "standard" -> StandardPricing
// "weekend" -> WeekendDiscountPricing
IPricingStrategy strategy = null; // TODO: Inicializar basado en strategyType
// TODO: Crear RentalService con la estrategia de precios
// Leer el número de vehículos
int vehicleCount = Convert.ToInt32(Console.ReadLine());
// TODO: Leer y añadir cada vehículo al servicio
// Para cada vehículo, leer:
// - tipo (car, motorcycle, truck)
// - matrícula
// - marca
// - tarifa diaria
// - valor específico del tipo (seats, engineCC o capacidad de carga)
// Leer el número de operaciones
int operationCount = Convert.ToInt32(Console.ReadLine());
// TODO: Procesar cada operación
// Operaciones: rent, return, available
//
// Para "rent":
// Leer customerName, licensePlate, days
// Salida: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
// O: "Rental failed: {licensePlate}"
//
// Para "return":
// Leer licensePlate
// Salida: "Returned: {licensePlate}" o "Return failed: {licensePlate}"
//
// Para "available":
// Muestra cada vehículo disponible como:
// "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
}
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy13Desafíos finales
Plataforma de e-learningComponente de personaje de juegoServicio de alquiler de vehículos2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantesPractica por tu cuenta: Compilador de C# online