4. Design a Parking Lot System in Java: FAANG Interviews

Designing a parking lot system is a common problem in system design interviews that tests your understanding of object-oriented principles, data structures, and problem-solving skills. In this article, we’ll walk through the design of a parking lot system that can manage different vehicle types, allocate parking spots, and retrieve them efficiently using Java.

Key Concepts

  • Object-Oriented Design: We’ll be using a class hierarchy to represent different components in the parking lot system.
  • Polymorphism and Abstraction: Different vehicle types (e.g., motorcycle, compact, and large vehicles) will be handled through a common interface or abstract class.
  • Efficient Data Structures: We’ll use a HashMap to store and look up available parking spots efficiently.

Problem Overview

We are tasked with designing a parking lot system that:

  • Can accommodate multiple vehicle types.
  • Efficiently allocates and deallocates parking spots.
  • Allows the system to find available spots in an optimal way.

Class Hierarchy

Our system will consist of a few key entities:

  1. Vehicle - Represents a generic vehicle.
  2. Motorcycle, CompactCar, LargeCar - Specialized types of vehicles.
  3. ParkingSpot - Represents a parking spot in the lot.
  4. ParkingLot - Manages the entire parking lot, including spot allocation and retrieval.

Let’s break down each component.

Step 1: Defining the Vehicle Class

The Vehicle class will be an abstract class or an interface. It will serve as the base class for all vehicle types. It will include the method signatures that every vehicle class will implement.

abstract class Vehicle {
    protected String vehicleId;
    protected int size;

    public Vehicle(String vehicleId, int size) {
        this.vehicleId = vehicleId;
        this.size = size;
    }

    public String getVehicleId() {
        return vehicleId;
    }

    public int getSize() {
        return size;
    }

    public abstract void park(ParkingLot parkingLot);
}

Step 2: Implementing Specific Vehicle Types

Now, let's create specific vehicle types that inherit from Vehicle. For this example, we'll define Motorcycle, CompactCar, and LargeCar.

class Motorcycle extends Vehicle {
    public Motorcycle(String vehicleId) {
        super(vehicleId, 1); // Motorcycle requires 1 unit of space
    }

    @Override
    public void park(ParkingLot parkingLot) {
        parkingLot.allocateSpot(this);
    }
}

class CompactCar extends Vehicle {
    public CompactCar(String vehicleId) {
        super(vehicleId, 2); // Compact car requires 2 units of space
    }

    @Override
    public void park(ParkingLot parkingLot) {
        parkingLot.allocateSpot(this);
    }
}

class LargeCar extends Vehicle {
    public LargeCar(String vehicleId) {
        super(vehicleId, 3); // Large car requires 3 units of space
    }

    @Override
    public void park(ParkingLot parkingLot) {
        parkingLot.allocateSpot(this);
    }
}

Step 3: Creating the ParkingSpot Class

A ParkingSpot class will represent a single parking spot in the lot. It will store information about whether it is occupied and which vehicle is parked in it.

class ParkingSpot {
    private int spotId;
    private boolean isOccupied;
    private Vehicle vehicle;

    public ParkingSpot(int spotId) {
        this.spotId = spotId;
        this.isOccupied = false;
    }

    public boolean isOccupied() {
        return isOccupied;
    }

    public void park(Vehicle vehicle) {
        if (!isOccupied) {
            this.vehicle = vehicle;
            isOccupied = true;
        }
    }

    public void leave() {
        isOccupied = false;
        vehicle = null;
    }

    public int getSpotId() {
        return spotId;
    }
}

Step 4: Managing the Parking Lot

The ParkingLot class manages the allocation and deallocation of parking spots. It will include a map (HashMap) of parking spots and will be responsible for parking vehicles and checking available spots.

import java.util.HashMap;
import java.util.Map;

class ParkingLot {
    private Map<Integer, ParkingSpot> spots;

    public ParkingLot(int totalSpots) {
        spots = new HashMap<>();
        for (int i = 1; i <= totalSpots; i++) {
            spots.put(i, new ParkingSpot(i));
        }
    }

    public boolean allocateSpot(Vehicle vehicle) {
        for (Map.Entry<Integer, ParkingSpot> entry : spots.entrySet()) {
            ParkingSpot spot = entry.getValue();
            if (!spot.isOccupied() && spot.getSpotId() >= vehicle.getSize()) {
                spot.park(vehicle);
                System.out.println(vehicle.getVehicleId() + " parked in spot " + spot.getSpotId());
                return true;
            }
        }
        System.out.println("No available spot for " + vehicle.getVehicleId());
        return false;
    }

    public void deallocateSpot(int spotId) {
        ParkingSpot spot = spots.get(spotId);
        if (spot != null && spot.isOccupied()) {
            spot.leave();
            System.out.println("Spot " + spotId + " is now available.");
        }
    }
}

Step 5: Testing the Parking Lot System

Here’s how we can use the above classes to simulate a parking lot.

public class ParkingLotSystem {
    public static void main(String[] args) {
        ParkingLot lot = new ParkingLot(10); // Parking lot with 10 spots

        Vehicle bike = new Motorcycle("M1");
        Vehicle compactCar = new CompactCar("C1");
        Vehicle largeCar = new LargeCar("L1");

        bike.park(lot);       // Motorcycle parks in the lot
        compactCar.park(lot); // Compact car parks in the lot
        largeCar.park(lot);   // Large car parks in the lot

        lot.deallocateSpot(1); // Motorcycle leaves
    }
}

Summary

This design provides a simple and effective way to manage a parking lot system that can handle different types of vehicles. We have used the power of object-oriented design principles, like inheritance, polymorphism, and abstraction, to allow the system to scale easily by adding new vehicle types.

By utilizing efficient data structures, such as HashMap, we ensure that we can quickly find and manage parking spots. This approach guarantees that the system can efficiently allocate and deallocate parking spots while maintaining readability and scalability for future enhancements.

Please stay tune, I will update Point 5 of FANNG Interview series, Please check top 10 interview questions here.

0 comments:

Post a Comment