Serviço de Aluguel de Veículos
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy — lição 70 de 70.
Desafio
FácilVamos construir um serviço de aluguel de veículos que reúne herança, interfaces e o padrão Strategy! Você criará um sistema onde diferentes tipos de veículos podem ser alugados usando estratégias de preços flexíveis - demonstrando como a POO permite uma lógica de negócios sustentável e extensível.
Você organizará seu código em seis arquivos:
Vehicle.cs: Crie sua hierarquia de veículos no namespaceRental.Models. A classe baseVehicledeve ter as propriedades somente leituraLicensePlateeBrand, umaDailyRate(decimal) e uma propriedadeIsAvailablecom um setter privado controlado através dos métodosMarkAsRented()eMarkAsReturned(). Em seguida, crie três classes derivadas:Carcom uma propriedadeSeats,Motorcyclecom uma propriedadeEngineCCeTruckcom uma propriedadeCargoCapacity(decimal). Cada classe derivada deve chamar o construtor base e definir sua propriedade exclusiva.IPricingStrategy.cs: Defina a interfaceIPricingStrategyno namespaceRental.Pricingcom um único métodoCalculatePrice(Vehicle vehicle, int days)que retorna um decimal.PricingStrategies.cs: Implemente duas estratégias de preços no namespaceRental.Pricing.StandardPricingsimplesmente multiplica a taxa diária do veículo pelo número de dias.WeekendDiscountPricingaplica um desconto de 10% (multiplica por 0.9) se o aluguel for por 2 ou mais dias, caso contrário, usa o cálculo padrão.RentalRecord.cs: Crie uma classeRentalno namespaceRental.Modelspara rastrear os aluguéis. Ela deve ter propriedades somente leitura paraCustomerName(string),Vehicle(Vehicle),Days(int) eTotalPrice(decimal), todas definidas através do construtor.RentalService.cs: Crie uma classeRentalServiceno namespaceRental.Servicesque gerencia a frota e processa os aluguéis. Ela recebe umaIPricingStrategyatravés de seu construtor (injeção de dependência). Implemente:AddVehicle(Vehicle vehicle)- adiciona um veículo à frotaRentVehicle(string customerName, string licensePlate, int days)- retorna um objetoRentalse o veículo existir e estiver disponível, caso contrário, retornanull. Lembre-se de marcar o veículo como alugado e calcular o preço usando a estratégia injetada.ReturnVehicle(string licensePlate)- marca o veículo como disponível, retornatruese for bem-sucedidoGetAvailableVehicles()- retorna uma lista de todos os veículos disponíveis
Program.cs: Reúna tudo criando veículos, configurando o serviço com uma estratégia de preços e processando operações de aluguel com base na entrada.
Você receberá as seguintes entradas:
- Estratégia de preços a ser usada (
standardouweekend) - Número de veículos a serem adicionados
- Para cada veículo: tipo (
car,motorcycleoutruck), placa, marca, taxa diária e valor específico do tipo (assentos, cilindradas ou capacidade de carga) - Número de operações a serem realizadas
- Para cada operação: a ação seguida pelos dados relevantes
Formatos de operação:
rent
{customerName}
{licensePlate}
{days}
return
{licensePlate}
availableFormatos de saída:
- Sucesso no aluguel:
Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice} - Falha no aluguel:
Rental failed: {licensePlate} - Sucesso na devolução:
Returned: {licensePlate} - Falha na devolução:
Return failed: {licensePlate} - Disponíveis: Imprima cada veículo disponível como
{Type}: {Brand} ({LicensePlate}) - {DailyRate}/dayonde Type é "Car", "Motorcycle" ou "Truck"
Por exemplo, se as entradas forem:
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-123A saída deve 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
Rental failed: ABC-123
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Returned: ABC-123Observe como a estratégia de preços é injetada no serviço - você poderia facilmente trocar StandardPricing por WeekendDiscountPricing sem alterar nada no código do RentalService. Este é o poder do padrão Strategy combinado com a injeção de dependência!
Experimente você mesmo
using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;
class Program
{
public static void Main(string[] args)
{
// Lê o tipo de estratégia de precificação
string strategyType = Console.ReadLine();
// TODO: Criar a estratégia de precificação apropriada com base na entrada
// "standard" -> StandardPricing
// "weekend" -> WeekendDiscountPricing
IPricingStrategy strategy = null; // TODO: Inicializar com base em strategyType
// TODO: Criar RentalService com a estratégia de precificação
// Lê o número de veículos
int vehicleCount = Convert.ToInt32(Console.ReadLine());
// TODO: Ler e adicionar cada veículo ao serviço
// Para cada veículo, ler:
// - type (car, motorcycle, truck)
// - license plate
// - brand
// - daily rate
// - valor específico do tipo (seats, engineCC, ou cargo capacity)
// Lê o número de operações
int operationCount = Convert.ToInt32(Console.ReadLine());
// TODO: Processar cada operação
// Operações: rent, return, available
//
// Para "rent":
// Ler customerName, licensePlate, days
// Saída: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
// Ou: "Rental failed: {licensePlate}"
//
// Para "return":
// Ler licensePlate
// Saída: "Returned: {licensePlate}" ou "Return failed: {licensePlate}"
//
// Para "available":
// Exibir cada veículo disponível como:
// "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
}
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy13Desafios Finais
Plataforma de E-learningComponente de Personagem de JogoServiço de Aluguel de Veículos2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de Métodos