Table of contents
Car Rental System
A Car Rental System is a software built to handle the renting of automobiles for a short period of time, generally ranging from a few hours to a few weeks. A car rental system often has numerous local branches (to allow its user to return a vehicle to a different location), and primarily located near airports or busy city areas.
Features
We will focus on the following set of requirements while designing our Car Rental System:
The system will support the renting of different automobiles like cars, trucks, SUVs, vans, and motorcycles.
Each vehicle should be added with a unique barcode and other details, including a parking stall number which helps to locate the vehicle.
The system should be able to retrieve information like which member took a particular vehicle or what vehicles have been rented out by a specific member.
The system should collect a late-fee for vehicles returned after the due date.
Members should be able to search the vehicle inventory and reserve any available vehicle.
The system should be able to send notifications whenever the reservation is approaching the pick-up date, as well as when the vehicle is nearing the due date or has not been returned within the due date.
The system will be able to read barcodes from vehicles.
Members should be able to cancel their reservations.
The system should maintain a vehicle log to track all events related to the vehicles.
Members can add rental insurance to their reservation.
Members can rent additional equipment, like navigation, child seat, ski rack, etc.
Members can add additional services to their reservation, such as roadside assistance, additional driver, wifi, etc.
Rough Solution (LLD-Machine Coding)
// Enums representing various statuses in the car rental system
public enum BillItemType {
BASE_CHARGE, ADDITIONAL_SERVICE, FINE, DAMAGE_CHARGE, OTHER
}
public enum VehicleLogType {
ACCIDENT, FUELING, CLEANING_SERVICE, OIL_CHANGE, REPAIR, INSPECTION, OTHER
}
public enum VanType {
PASSENGER, CARGO
}
public enum CarType {
ECONOMY, COMPACT, INTERMEDIATE, STANDARD, FULL_SIZE, PREMIUM, LUXURY, SPORTS
}
public enum VehicleStatus {
AVAILABLE, RESERVED, LOANED, LOST, BEING_SERVICED, MAINTENANCE, OTHER
}
public enum ReservationStatus {
ACTIVE, PENDING, CONFIRMED, COMPLETED, CANCELED, NONE, EXPIRED
}
public enum AccountStatus {
ACTIVE, CLOSED, CANCELED, BLACKLISTED, BLOCKED, UNDER_REVIEW
}
public enum PaymentStatus {
UNPAID, PENDING, COMPLETED, FAILED, DECLINED, CANCELED, ABANDONED, SETTLING, SETTLED, REFUNDED
}
// Address class to represent the address of a person or a location
public class Address {
private String streetAddress;
private String city;
private String state;
private String zipCode;
private String country;
}
// Abstract Person class to represent common attributes of people
public class Person {
private String name;
private Address address;
private String email;
private String phone;
}
// Abstract Account class to manage user account details
public abstract class Account {
private String id;
private String password;
private AccountStatus status;
private Person person;
public boolean resetPassword() {
System.out.println("Password reset for account: " + id);
return true;
}
}
// Concrete class for Members who can reserve vehicles
public class Member extends Account {
private int totalVehiclesReserved;
public List<VehicleReservation> getReservations() {
return new ArrayList<>();
}
}
// Receptionist class responsible for vehicle and worker management
public class Receptionist extends Account {
private Date dateJoined;
public List<Member> searchMember(String name) {
System.out.println("Searching for member: " + name);
return new ArrayList<>();
}
public boolean reserveVehicle(VehicleReservation reservation) {
System.out.println("Vehicle reserved by receptionist.");
return true;
}
}
// Worker class responsible for managing vehicle returns
public class Worker extends Account {
public boolean updateVehicleLog(Vehicle vehicle, VehicleLog log) {
vehicle.getLog().add(log);
System.out.println("Vehicle log updated.");
return true;
}
}
// Abstract class representing vehicles
public abstract class Vehicle {
private String licenseNumber;
private String stockNumber;
private int passengerCapacity;
private String barcode;
private boolean hasSunroof;
private VehicleStatus status;
private String model;
private String make;
private int manufacturingYear;
private int mileage;
private List<VehicleLog> log = new ArrayList<>();
public boolean reserveVehicle() {
this.status = VehicleStatus.RESERVED;
System.out.println("Vehicle reserved.");
return true;
}
public boolean returnVehicle() {
this.status = VehicleStatus.AVAILABLE;
System.out.println("Vehicle returned.");
return true;
}
public List<VehicleLog> getLog() {
return log;
}
}
// Concrete class for Car vehicles
public class Car extends Vehicle {
private CarType type;
public Car(CarType type) {
this.type = type;
}
// Other Car-specific methods can be added here
}
// Concrete class for Van vehicles
public class Van extends Vehicle {
private VanType type;
public Van(VanType type) {
this.type = type;
}
// Other Van-specific methods can be added here
}
// Concrete class for Truck vehicles
public class Truck extends Vehicle {
private String type;
public Truck(String type) {
this.type = type;
}
// Other Truck-specific methods can be added here
}
// VehicleLog class to manage logs for a vehicle
public class VehicleLog {
private String id;
private VehicleLogType type;
private String description;
private Date creationDate;
public boolean update() {
System.out.println("Vehicle log updated.");
return true;
}
public List<VehicleLogType> searchByLogType(VehicleLogType type) {
return new ArrayList<>();
}
}
// Concrete class for managing vehicle reservations
public class VehicleReservation {
private String reservationNumber;
private Date creationDate;
private ReservationStatus status;
private Date dueDate;
private Date returnDate;
private String pickupLocationName;
private String returnLocationName;
private int customerID;
private Vehicle vehicle;
private Bill bill;
private List<AdditionalDriver> additionalDrivers = new ArrayList<>();
private List<Notification> notifications = new ArrayList<>();
private List<RentalInsurance> insurances = new ArrayList<>();
private List<Equipment> equipments = new ArrayList<>();
private List<Service> services = new ArrayList<>();
public static VehicleReservation fetchReservationDetails(String reservationNumber) {
System.out.println("Fetching reservation details for: " + reservationNumber);
return new VehicleReservation();
}
public List<AdditionalDriver> getAdditionalDrivers() {
return additionalDrivers;
}
public boolean completeReservation() {
this.status = ReservationStatus.COMPLETED;
System.out.println("Reservation completed.");
return true;
}
}
// AdditionalDriver class representing extra drivers for a reservation
public class AdditionalDriver {
private String driverID;
private Person person;
public AdditionalDriver(String driverID, Person person) {
this.driverID = driverID;
this.person = person;
}
}
// CarRentalLocation class to manage different rental locations
public class CarRentalLocation {
private String name;
private Address location;
public Address getLocation() {
return location;
}
}
// CarRentalSystem class to manage the entire rental system
public class CarRentalSystem {
private String name;
private List<CarRentalLocation> locations = new ArrayList<>();
public boolean addNewLocation(CarRentalLocation location) {
locations.add(location);
System.out.println("New location added: " + location.getLocation());
return true;
}
}
// Interface for search functionality
public interface Search {
public List<Vehicle> searchByType(String type);
public List<Vehicle> searchByModel(String model);
}
// Concrete class for VehicleInventory implementing Search functionality
public class VehicleInventory implements Search {
private HashMap<String, List<Vehicle>> vehicleTypes = new HashMap<>();
private HashMap<String, List<Vehicle>> vehicleModels = new HashMap<>();
@Override
public List<Vehicle> searchByType(String query) {
System.out.println("Searching vehicles by type: " + query);
return vehicleTypes.getOrDefault(query, new ArrayList<>());
}
@Override
public List<Vehicle> searchByModel(String query) {
System.out.println("Searching vehicles by model: " + query);
return vehicleModels.getOrDefault(query, new ArrayList<>());
}
}
// Notification class and Observer pattern implementation
interface Observer {
void update(String message);
}
class SystemNotifier {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
class Customer implements Observer {
private String name;
private Account account;
public Customer(String name, Account account) {
this.name = name;
this.account = account;
}
@Override
public void update(String message) {
System.out.println("Notification for " + name + ": " + message);
}
}
// Command pattern to handle vehicle reservations
interface Command {
void execute();
}
class ReserveVehicleCommand implements Command {
private VehicleReservation reservation;
public ReserveVehicleCommand(VehicleReservation reservation) {
this.reservation = reservation;
}
@Override
public void execute() {
reservation.completeReservation();
}
}
// Main class to demonstrate the implementation of various patterns
public class Main {
public static void main(String[] args) {
// Create the system notifier and add customers as observers
SystemNotifier notifier = new SystemNotifier();
Customer alice = new Customer("Alice", new Member());
Customer bob = new Customer("Bob", new Member());
notifier.addObserver(alice);
notifier.addObserver(bob);
// Notify customers about overdue vehicle reservation
notifier.notifyObservers("Your vehicle reservation is overdue!");
// Create and complete a vehicle reservation using the Command pattern
VehicleReservation reservation = new VehicleReservation();
Command reserveCommand = new ReserveVehicleCommand(reservation);
reserveCommand.execute();
// Perform a search for vehicles by type
VehicleInventory inventory = new VehicleInventory();
inventory.searchByType("SUV");
}
}