Menu
Coddy logo textTech

Сервис аренды транспорта

Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 110 из 110.

challenge icon

Задание

Легко

Поздравляем с достижением финального испытания курса по ООП! Давайте создадим комплексный Сервис аренды автомобилей (Vehicle Rental Service), который объединит все, что вы изучили: абстрактные классы, наследование, инкапсуляцию, паттерн Состояние (State), паттерн Фабрика (Factory) и дженерики.

Ваш сервис аренды будет управлять различными типами транспортных средств, отслеживать их состояния доступности, обрабатывать аренду и вести учет клиентов. Вы организуете это в семи файлах:

  • vehicle_state.dart: Создайте абстрактный класс VehicleState, который определяет поведение транспортных средств в различных состояниях. Включите абстрактный метод String getStatus() и bool canRent(). Затем создайте три конкретных состояния:
    • AvailableState — возвращает Available и разрешает аренду
    • RentedState — возвращает Rented и не разрешает аренду
    • MaintenanceState — возвращает In Maintenance и не разрешает аренду
  • vehicle.dart: Создайте абстрактный класс Vehicle с final id (String), final model (String), приватным полем _dailyRate (double) с геттером и приватным полем _state (VehicleState), инициализированным как AvailableState. Включите:
    • Геттер status, который возвращает статус состояния
    • bool isAvailable() — проверяет, позволяет ли текущее состояние аренду
    • void setState(VehicleState state) — изменяет состояние транспортного средства
    • Абстрактный метод double calculateRentalCost(int days)
    • Абстрактный метод String getRequirements() — возвращает любые специальные требования
    Переопределите toString(), чтобы он возвращал [Type] model (id) - status, где Type — это тип времени выполнения (runtime type).
  • vehicles.dart: Создайте три типа транспортных средств, расширяющих Vehicle:
    • Car — стандартная стоимость аренды равна дневной ставке, умноженной на количество дней. Требования: Valid driver's license
    • Motorcycle — стоимость аренды равна дневной ставке, умноженной на количество дней, со скидкой 10%. Требования: Motorcycle license, Age 21+
    • Truck — стоимость аренды равна дневной ставке, умноженной на количество дней, плюс фиксированная комиссия $50. Требования: Commercial license, Deposit required
  • vehicle_factory.dart: Создайте класс VehicleFactory со статическим методом Vehicle create(String type, String id, String model, double dailyRate), который возвращает соответствующее транспортное средство в зависимости от типа (car, motorcycle или truck). Для неизвестных типов по умолчанию создавайте Car.
  • customer.dart: Создайте класс Customer с id (String), name (String) и приватным списком записей об аренде (список Strings). Включите:
    • addRental(String vehicleInfo) — добавляет запись об аренде
    • getRentalCount() — возвращает количество аренд
    • bool isEligible() — возвращает true, если у клиента менее 3 активных аренд
    Переопределите toString(), чтобы он возвращал Customer: name (id) - X rentals.
  • rental_service.dart: Создайте класс RentalService, использующий дженерики с List<Vehicle> для автопарка и List<Customer> для клиентов. Включите:
    • addVehicle(Vehicle vehicle) — добавляет в автопарк, выводит Added: vehicle.toString()
    • registerCustomer(Customer customer) — регистрирует клиента
    • rentVehicle(String customerId, String vehicleId, int days) — если клиент существует, имеет право на аренду и транспортное средство доступно: меняет состояние ТС на Rented, добавляет аренду клиенту, выводит customerId rented vehicleId for X days. Cost: $Y (Y отформатировано до 2 знаков после запятой). В противном случае выведите соответствующее сообщение: Customer not found, Customer not eligible, Vehicle not found или Vehicle not available
    • returnVehicle(String vehicleId) — устанавливает состояние ТС в Available, выводит vehicleId returned
    • sendToMaintenance(String vehicleId) — устанавливает состояние ТС в Maintenance, выводит vehicleId sent to maintenance
    • getAvailableVehicles() — возвращает список доступных транспортных средств
  • main.dart: Продемонстрируйте работу вашего сервиса аренды. Создайте RentalService и используйте фабрику, чтобы добавить три транспортных средства:
    • Легковой автомобиль: V001, Toyota Camry, $45/день
    • Мотоцикл: V002, Honda CBR, $35/день
    • Грузовик: V003, Ford F-150, $75/день
    Зарегистрируйте клиента (C001, Alice Johnson) и выведите информацию о клиенте. Выведите требования для грузовика. Сдайте автомобиль в аренду Элис на 3 дня. Попробуйте снова арендовать тот же автомобиль (должно не получиться). Отправьте мотоцикл на техническое обслуживание. Выведите количество доступных транспортных средств в формате Available vehicles: X. Верните автомобиль. Выведите итоговое количество доступных ТС.

Ожидаемый вывод:

Added: [Car] Toyota Camry (V001) - Available
Added: [Motorcycle] Honda CBR (V002) - Available
Added: [Truck] Ford F-150 (V003) - Available
Customer: Alice Johnson (C001) - 0 rentals
Commercial license, Deposit required
C001 rented V001 for 3 days. Cost: $135.00
Vehicle not available
V002 sent to maintenance
Available vehicles: 1
V001 returned
Available vehicles: 2

Попробуйте сами

import 'rental_service.dart';
import 'vehicle_factory.dart';
import 'customer.dart';

void main() {
  // TODO: Создать экземпляр RentalService
  
  // TODO: Использовать VehicleFactory для создания и добавления трех транспортных средств:
  // - Car: V001, Toyota Camry, $45/день
  // - Motorcycle: V002, Honda CBR, $35/день
  // - Truck: V003, Ford F-150, $75/день
  
  // TODO: Зарегистрировать клиента (C001, Alice Johnson)
  
  // TODO: Вывести информацию о клиенте
  
  // TODO: Вывести требования для грузовика (найти грузовик и вызвать getRequirements())
  
  // TODO: Арендовать автомобиль (V001) для Alice (C001) на 3 дня
  
  // TODO: Попробовать арендовать автомобиль снова (должно завершиться неудачей — недоступен)
  
  // TODO: Отправить мотоцикл (V002) на техническое обслуживание
  
  // TODO: Вывести количество доступных транспортных средств в формате 'Available vehicles: X'
  
  // TODO: Вернуть автомобиль (V001)
  
  // TODO: Вывести итоговое количество доступных транспортных средств
}

Все уроки раздела Объектно-ориентированное программирование