Skip to main content

Command Palette

Search for a command to run...

๐Ÿš— Designing the Perfect Parking Lot System: A Complete Guide

Updated
โ€ข18 min read
๐Ÿš— Designing the Perfect Parking Lot System: A Complete Guide

Ever wondered how modern parking lots seamlessly manage hundreds of vehicles while keeping track of every spot, payment, and customer? Let's dive into the fascinating world of parking lot system design!


๐ŸŽฏ The Challenge

Picture this: You're tasked with designing a parking lot system for a busy shopping mall. It needs to handle multiple floors, different vehicle types, various payment methods, and provide real-time information to drivers. Sounds complex? It is! But with the right approach, we can break it down into manageable components.

๐Ÿ“‹ What We Need to Achieve

Functional Requirements Breakdown

Our parking lot system needs to be a multi-talented performer:

๐Ÿข Multi-Floor Management

  • Handle multiple levels of parking

  • Track capacity per floor

  • Direct traffic efficiently between floors

๐Ÿšช Smart Entry & Exit System

  • Multiple entry/exit points to prevent bottlenecks

  • Automated ticket dispensing

  • License plate recognition (future enhancement)

๐ŸŽซ Ticketing System

  • Generate unique tickets with timestamps

  • Track parking duration

  • Secure ticket validation

๐Ÿ’ณ Flexible Payment Options

  • Cash payments at automated machines

  • Credit/debit card processing

  • Customer service portal for assistance

  • Mobile app integration (future scope)

๐Ÿ“Š Intelligent Capacity Management

  • Real-time occupancy tracking

  • Prevent overcrowding

  • Queue management during peak hours

๐Ÿ…ฟ๏ธ Diverse Parking Spots

Because one size doesn't fit all:

  • Compact spots - For smaller vehicles

  • Large spots - For SUVs and trucks

  • Handicapped spots - ADA compliant with easy access

  • Motorcycle spots - Optimized for two-wheelers

  • Electric vehicle spots - With charging infrastructure

โšก Electric Vehicle Support

The future is electric, and we're ready:

  • Charging stations integrated with payment systems

  • Different charging speeds (Level 1, 2, and DC fast charging)

  • Real-time charging status monitoring

๐Ÿ“บ Information Display System

  • LED boards showing available spots per floor

  • Entry point displays with real-time updates

  • Mobile app with live availability

๐Ÿ’ฐ Dynamic Pricing Model

  • Hourly rate structure

  • Peak/off-peak pricing

  • Early bird discounts

  • Monthly pass options


๐Ÿ—๏ธ System Architecture Design

Why This Approach?

I'm designing this system with a microservices architecture because it offers:

  • Scalability: Each component can scale independently

  • Maintainability: Easy to update individual services

  • Reliability: If one service fails, others continue working

  • Technology Flexibility: Different services can use different tech stacks

Core Components

           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ”‚                    PARKING LOT SYSTEM                  โ”‚
           โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
           โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
           โ”‚  โ”‚   Entry     โ”‚  โ”‚   Display   โ”‚  โ”‚    Exit     โ”‚     โ”‚
           โ”‚  โ”‚  Management โ”‚  โ”‚   Service   โ”‚  โ”‚ Management  โ”‚     โ”‚
           โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
           โ”‚         โ”‚                 โ”‚                 โ”‚          โ”‚
           โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ”‚
           โ”‚                           โ”‚                            โ”‚
           โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
           โ”‚  โ”‚   Parking   โ”‚  โ”‚   Central   โ”‚  โ”‚   Payment   โ”‚     โ”‚
           โ”‚  โ”‚    Spot     โ”‚โ—„โ”€โ”ค Management  โ”œโ”€โ–บโ”‚   Service   โ”‚     โ”‚
           โ”‚  โ”‚  Management โ”‚  โ”‚   System    โ”‚  โ”‚             โ”‚     โ”‚
           โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
           โ”‚                           โ”‚                            โ”‚
           โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
           โ”‚  โ”‚   Vehicle   โ”‚  โ”‚  Charging   โ”‚  โ”‚ Notificationโ”‚     โ”‚
           โ”‚  โ”‚ Management  โ”‚  โ”‚  Station    โ”‚  โ”‚   Service   โ”‚     โ”‚
           โ”‚  โ”‚             โ”‚  โ”‚ Management  โ”‚  โ”‚             โ”‚     โ”‚
           โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ง Detailed Component Design

1. Entry Management System

Why this approach? We need a robust entry system that can handle high traffic while maintaining security and accuracy.

Key Features:

  • Automated ticket dispensing

  • Vehicle type detection (cameras + sensors)

  • Real-time capacity checking

  • Queue management

public class EntryGate {
    private ParkingLot parkingLot;
    private TicketGenerator ticketGenerator;
    private GateController gateController;

    public Ticket processVehicleEntry(VehicleType vehicleType) {
        if (parkingLot.hasAvailableSpots(vehicleType)) {
            Ticket ticket = ticketGenerator.generateTicket(vehicleType);
            gateController.openGate();
            parkingLot.updateOccupancy(vehicleType, 1);
            logEntry(ticket);
            return ticket;
        } else {
            displayMessage("LOT FULL - Please try alternative parking");
            return null;
        }
    }

    private void logEntry(Ticket ticket) {
        System.out.println("Vehicle entered: " + ticket.getTicketId() + 
                          " at " + ticket.getEntryTime());
    }
}

2. Parking Spot Management

Our Strategy: We'll use a hierarchical approach - Building โ†’ Floor โ†’ Zone โ†’ Spot. This makes the system incredibly scalable.

Spot Types & Specifications

Spot TypeDimensionsSpecial Features
๐Ÿš— Compact8' ร— 16'Standard parking
๐Ÿš™ Large9' ร— 20'For SUVs/Trucks
โ™ฟ Handicapped11' ร— 20'Wider access + ramp
๐Ÿ๏ธ Motorcycle4' ร— 8'Secured area
โšก Electric9' ร— 18'Charging station

Why these dimensions? Based on standard automotive sizes and accessibility requirements, ensuring comfortable parking while maximizing capacity.

3. Payment Processing System

Multi-Modal Payment Strategy:

Payment Flow:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Ticket    โ”‚โ”€โ”€โ”€โ–บโ”‚  Calculate  โ”‚โ”€โ”€โ”€โ–บโ”‚   Payment   โ”‚
โ”‚ Validation  โ”‚    โ”‚    Fee      โ”‚    โ”‚ Processing  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                   โ”‚                   โ”‚
       โ–ผ                   โ–ผ                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Barcode   โ”‚    โ”‚   Hourly    โ”‚    โ”‚    Cash     โ”‚
โ”‚   Scanner   โ”‚    โ”‚   Rates     โ”‚    โ”‚   Credit    โ”‚
โ”‚             โ”‚    โ”‚   Peak/Off  โ”‚    โ”‚   Mobile    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. Electric Vehicle Charging Integration

Why prioritize EV support? With the automotive industry's shift toward electrification, EV support isn't just nice-to-haveโ€”it's essential for future-proofing.

Charging Station Features:

  • Multiple connector types (Type 1, Type 2, CCS, CHAdeMO)

  • Integrated payment processing

  • Real-time charging status

  • Mobile app notifications

5. Real-Time Display System

Information Architecture:

Entry Display Board:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚    PARKING AVAILABILITY      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ FLOOR 1:  ๐Ÿš— 12  ๐Ÿš™ 5  โšก 3    โ”‚
โ”‚ FLOOR 2:  ๐Ÿš— 8   ๐Ÿš™ 2  โšก 1    |
โ”‚ FLOOR 3:  ๐Ÿš— 15  ๐Ÿš™ 7  โšก 4    |
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ™ฟ HANDICAPPED: 6 AVAILABLE   โ”‚
โ”‚ ๐Ÿ๏ธ MOTORCYCLE: 12 AVAILABLE  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”„ System Workflow

The Complete Journey

  1. ๐Ÿš— Vehicle Approaches

    • License plate recognition (optional)

    • Vehicle type detection

    • Display available spots

  2. ๐ŸŽซ Entry Process

    • Ticket generation with QR code

    • Barrier opens automatically

    • Real-time capacity update

  3. ๐Ÿ…ฟ๏ธ Parking Assignment

    • Smart routing to available spots

    • Floor-specific guidance

    • Spot reservation (premium feature)

  4. โฐ Duration Tracking

    • Continuous monitoring

    • Overstay alerts

    • Dynamic pricing calculation

  5. ๐Ÿ’ณ Payment Processing

    • Multiple payment options

    • Receipt generation

    • Grace period for exit

  6. ๐Ÿšช Exit Process

    • Ticket validation

    • Payment confirmation

    • Automated barrier opening


๐Ÿ“ˆ Scalability & Performance

Horizontal Scaling Strategy

Why this matters: A successful parking lot will need to expand. Our design supports:

  • Adding new floors: Plug-and-play architecture

  • Increasing capacity: Linear scaling without system redesign

  • Multi-location support: Centralized management with local processing

Performance Optimization

Load Balancing Strategy:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Entry     โ”‚    โ”‚   Entry     โ”‚    โ”‚   Entry     โ”‚
โ”‚   Gate 1    โ”‚    โ”‚   Gate 2    โ”‚    โ”‚   Gate 3    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                   โ”‚                   โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚    Load Balancer        โ”‚
              โ”‚  (Traffic Distribution) โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚   Central Processing    โ”‚
              โ”‚      System             โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ› ๏ธ Technology Stack Recommendations

Backend Services

  • Language: Java with Spring Boot for business logic (examples provided above)

  • Database: PostgreSQL for transactional data, Redis for caching

  • Message Queue: RabbitMQ for async processing

  • API Gateway: nginx for load balancing

  • Framework: Spring Boot with Spring Security for authentication

Hardware Integration

  • Sensors: Ultrasonic/magnetic for spot detection

  • Cameras: License plate recognition

  • Payment Terminals: EMV-compliant card readers

  • Display Systems: LED matrices with network connectivity

Mobile & Web Interface

  • Frontend: React Native for cross-platform mobile app

  • Backend API: RESTful services with real-time WebSocket updates

  • Admin Dashboard: React.js for management interface


๐Ÿ”’ Security & Compliance

Data Protection

  • PCI DSS Compliance: For payment processing

  • Data Encryption: All sensitive data encrypted at rest and in transit

  • Access Control: Role-based permissions for different user types

Physical Security

  • CCTV Integration: 24/7 monitoring with motion detection

  • Emergency Systems: Fire safety and evacuation protocols

  • Access Control: Secure areas for staff and equipment


๐ŸŽฏ Implementation Roadmap

Phase 1: Core Functionality (Months 1-3)

  • โœ… Basic entry/exit system

  • โœ… Ticket generation and validation

  • โœ… Payment processing

  • โœ… Spot occupancy tracking

Phase 2: Enhanced Features (Months 4-6)

  • โœ… Multi-floor support

  • โœ… Different vehicle types

  • โœ… Real-time display boards

  • โœ… Mobile app (basic version)

Phase 3: Advanced Features (Months 7-9)

  • โœ… Electric vehicle charging

  • โœ… License plate recognition

  • โœ… Dynamic pricing

  • โœ… Analytics dashboard

Phase 4: AI & Optimization (Months 10-12)

  • โœ… Predictive analytics

  • โœ… Smart routing algorithms

  • โœ… Automated maintenance alerts

  • โœ… Customer behavior analysis


๐Ÿ“Š Success Metrics

Key Performance Indicators

MetricTargetWhy It Matters
Average Entry Time< 30 secondsCustomer satisfaction
System Uptime99.9%Reliability
Payment Success Rate> 98%Revenue protection
Spot Utilization> 85%Efficiency
Customer Satisfaction> 4.5/5Retention

๐Ÿ”ฎ Future Enhancements

Smart City Integration

  • Traffic Management: Integration with city traffic systems

  • Environmental Monitoring: Air quality sensors

  • Energy Management: Solar panels and battery storage

AI-Powered Features

  • Predictive Maintenance: IoT sensors for proactive repairs

  • Demand Forecasting: Machine learning for capacity planning

  • Personalized Experience: Custom recommendations for frequent users


๐ŸŽ‰ Conclusion

Designing a modern parking lot system is like orchestrating a complex symphonyโ€”every component must work in perfect harmony. By focusing on modularity, scalability, and user experience, we create a system that not only meets today's needs but adapts to tomorrow's challenges.

The key to success lies in:

  • ๐Ÿ—๏ธ Solid Architecture: Microservices for flexibility

  • ๐Ÿ‘ฅ User-Centric Design: Making parking effortless

  • ๐Ÿ”ฎ Future-Ready Technology: Embracing electric vehicles and smart city concepts

  • ๐Ÿ“ˆ Data-Driven Decisions: Analytics for continuous improvement

Remember, a great parking lot system doesn't just store carsโ€”it enhances the entire urban experience. Now, let's build something amazing! ๐Ÿš€


Ready to implement this system? The journey from concept to reality is just as exciting as the destination!


๐Ÿ’ป Implementation Examples

Let's dive into the actual Java code that brings our parking lot system to life! These examples show how to implement the core components with clean, maintainable code.

๐Ÿ—๏ธ Core Domain Models

// Enums for type safety and clarity
public enum VehicleType {
    MOTORCYCLE(1, "Motorcycle"),
    COMPACT_CAR(2, "Compact Car"), 
    LARGE_CAR(3, "Large Car"),
    TRUCK(4, "Truck"),
    ELECTRIC_CAR(2, "Electric Car");

    private final int spotsRequired;
    private final String displayName;

    VehicleType(int spotsRequired, String displayName) {
        this.spotsRequired = spotsRequired;
        this.displayName = displayName;
    }

    public int getSpotsRequired() { return spotsRequired; }
    public String getDisplayName() { return displayName; }
}

public enum SpotType {
    COMPACT(8, 16, VehicleType.COMPACT_CAR, VehicleType.MOTORCYCLE),
    LARGE(9, 20, VehicleType.LARGE_CAR, VehicleType.TRUCK, VehicleType.COMPACT_CAR),
    HANDICAPPED(11, 20, VehicleType.COMPACT_CAR, VehicleType.LARGE_CAR),
    MOTORCYCLE(4, 8, VehicleType.MOTORCYCLE),
    ELECTRIC(9, 18, VehicleType.ELECTRIC_CAR);

    private final int width;
    private final int length;
    private final Set<VehicleType> supportedVehicles;

    SpotType(int width, int length, VehicleType... supportedVehicles) {
        this.width = width;
        this.length = length;
        this.supportedVehicles = Set.of(supportedVehicles);
    }

    public boolean canAccommodate(VehicleType vehicleType) {
        return supportedVehicles.contains(vehicleType);
    }

    // Getters...
}

๐ŸŽซ Ticket Management System

import java.time.LocalDateTime;
import java.util.UUID;

public class Ticket {
    private final String ticketId;
    private final LocalDateTime entryTime;
    private final VehicleType vehicleType;
    private final String spotId;
    private LocalDateTime exitTime;
    private boolean isPaid;
    private BigDecimal amountPaid;

    public Ticket(VehicleType vehicleType, String spotId) {
        this.ticketId = generateTicketId();
        this.entryTime = LocalDateTime.now();
        this.vehicleType = vehicleType;
        this.spotId = spotId;
        this.isPaid = false;
    }

    private String generateTicketId() {
        return "TKT-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }

    public Duration getParkingDuration() {
        LocalDateTime endTime = exitTime != null ? exitTime : LocalDateTime.now();
        return Duration.between(entryTime, endTime);
    }

    public void markAsPaid(BigDecimal amount) {
        this.amountPaid = amount;
        this.isPaid = true;
    }

    // Getters and setters...
}

@Service
public class TicketService {
    private final Map<String, Ticket> activeTickets = new ConcurrentHashMap<>();
    private final PricingService pricingService;

    public TicketService(PricingService pricingService) {
        this.pricingService = pricingService;
    }

    public Ticket issueTicket(VehicleType vehicleType, String spotId) {
        Ticket ticket = new Ticket(vehicleType, spotId);
        activeTickets.put(ticket.getTicketId(), ticket);

        logger.info("Ticket issued: {} for vehicle type: {} at spot: {}", 
                   ticket.getTicketId(), vehicleType, spotId);

        return ticket;
    }

    public BigDecimal calculateFee(String ticketId) {
        Ticket ticket = activeTickets.get(ticketId);
        if (ticket == null) {
            throw new TicketNotFoundException("Ticket not found: " + ticketId);
        }

        return pricingService.calculateParkingFee(
            ticket.getVehicleType(), 
            ticket.getParkingDuration()
        );
    }

    public boolean processPayment(String ticketId, BigDecimal amount, PaymentMethod method) {
        Ticket ticket = activeTickets.get(ticketId);
        BigDecimal requiredAmount = calculateFee(ticketId);

        if (amount.compareTo(requiredAmount) >= 0) {
            ticket.markAsPaid(amount);
            return true;
        }
        return false;
    }
}

๐Ÿ…ฟ๏ธ Parking Spot Management

public class ParkingSpot {
    private final String spotId;
    private final SpotType spotType;
    private final int floor;
    private final String section;
    private boolean isOccupied;
    private boolean isReserved;
    private LocalDateTime lastUpdated;
    private String currentTicketId;

    public ParkingSpot(String spotId, SpotType spotType, int floor, String section) {
        this.spotId = spotId;
        this.spotType = spotType;
        this.floor = floor;
        this.section = section;
        this.isOccupied = false;
        this.isReserved = false;
        this.lastUpdated = LocalDateTime.now();
    }

    public boolean canAccommodate(VehicleType vehicleType) {
        return !isOccupied && !isReserved && spotType.canAccommodate(vehicleType);
    }

    public synchronized boolean occupy(String ticketId) {
        if (canAccommodate(null)) {
            this.isOccupied = true;
            this.currentTicketId = ticketId;
            this.lastUpdated = LocalDateTime.now();
            return true;
        }
        return false;
    }

    public synchronized void vacate() {
        this.isOccupied = false;
        this.currentTicketId = null;
        this.lastUpdated = LocalDateTime.now();
    }

    // Getters...
}

@Service
public class ParkingSpotService {
    private final Map<String, ParkingSpot> allSpots = new ConcurrentHashMap<>();
    private final Map<SpotType, List<ParkingSpot>> spotsByType = new EnumMap<>(SpotType.class);

    @PostConstruct
    public void initializeSpots() {
        // Initialize parking spots for multiple floors
        for (int floor = 1; floor <= 3; floor++) {
            createSpotsForFloor(floor);
        }
    }

    private void createSpotsForFloor(int floor) {
        // Create different types of spots per floor
        createSpots(SpotType.COMPACT, floor, "A", 20);
        createSpots(SpotType.LARGE, floor, "B", 15);
        createSpots(SpotType.HANDICAPPED, floor, "H", 4);
        createSpots(SpotType.MOTORCYCLE, floor, "M", 10);
        createSpots(SpotType.ELECTRIC, floor, "E", 8);
    }

    private void createSpots(SpotType type, int floor, String section, int count) {
        for (int i = 1; i <= count; i++) {
            String spotId = String.format("F%d-%s%02d", floor, section, i);
            ParkingSpot spot = new ParkingSpot(spotId, type, floor, section);

            allSpots.put(spotId, spot);
            spotsByType.computeIfAbsent(type, k -> new ArrayList<>()).add(spot);
        }
    }

    public Optional<ParkingSpot> findAvailableSpot(VehicleType vehicleType) {
        return spotsByType.values().stream()
            .flatMap(List::stream)
            .filter(spot -> spot.canAccommodate(vehicleType))
            .findFirst();
    }

    public Map<SpotType, Long> getAvailabilityByType() {
        return spotsByType.entrySet().stream()
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().stream()
                    .filter(spot -> !spot.isOccupied())
                    .count()
            ));
    }

    public Map<Integer, Map<SpotType, Long>> getAvailabilityByFloor() {
        return allSpots.values().stream()
            .filter(spot -> !spot.isOccupied())
            .collect(Collectors.groupingBy(
                ParkingSpot::getFloor,
                Collectors.groupingBy(
                    ParkingSpot::getSpotType,
                    Collectors.counting()
                )
            ));
    }
}

๐Ÿ’ณ Payment Processing System

public interface PaymentProcessor {
    PaymentResult processPayment(PaymentRequest request);
    boolean refund(String transactionId, BigDecimal amount);
}

@Component
public class CashPaymentProcessor implements PaymentProcessor {
    @Override
    public PaymentResult processPayment(PaymentRequest request) {
        // Simulate cash payment validation
        if (request.getAmount().compareTo(BigDecimal.ZERO) > 0) {
            return PaymentResult.success(
                generateTransactionId(),
                request.getAmount(),
                "Cash payment processed"
            );
        }
        return PaymentResult.failure("Invalid cash amount");
    }

    private String generateTransactionId() {
        return "CASH-" + System.currentTimeMillis();
    }

    @Override
    public boolean refund(String transactionId, BigDecimal amount) {
        // Cash refunds require manual processing
        logger.info("Manual cash refund required: {} for amount: {}", 
                   transactionId, amount);
        return true;
    }
}

@Component
public class CreditCardPaymentProcessor implements PaymentProcessor {
    private final PaymentGateway paymentGateway;

    public CreditCardPaymentProcessor(PaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }

    @Override
    public PaymentResult processPayment(PaymentRequest request) {
        try {
            // Validate card details
            if (!isValidCard(request.getCardDetails())) {
                return PaymentResult.failure("Invalid card details");
            }

            // Process through payment gateway
            GatewayResponse response = paymentGateway.charge(
                request.getCardDetails(),
                request.getAmount(),
                "Parking Fee - " + request.getTicketId()
            );

            if (response.isSuccessful()) {
                return PaymentResult.success(
                    response.getTransactionId(),
                    request.getAmount(),
                    "Card payment successful"
                );
            } else {
                return PaymentResult.failure(response.getErrorMessage());
            }

        } catch (PaymentException e) {
            logger.error("Payment processing failed", e);
            return PaymentResult.failure("Payment processing error");
        }
    }

    private boolean isValidCard(CardDetails cardDetails) {
        return cardDetails != null && 
               cardDetails.getCardNumber() != null &&
               cardDetails.getExpiryDate().isAfter(LocalDate.now()) &&
               cardDetails.getCvv() != null;
    }

    @Override
    public boolean refund(String transactionId, BigDecimal amount) {
        try {
            return paymentGateway.refund(transactionId, amount).isSuccessful();
        } catch (PaymentException e) {
            logger.error("Refund failed for transaction: {}", transactionId, e);
            return false;
        }
    }
}

@Service
public class PaymentService {
    private final Map<PaymentMethod, PaymentProcessor> processors;
    private final PaymentRepository paymentRepository;

    public PaymentService(List<PaymentProcessor> processors, 
                         PaymentRepository paymentRepository) {
        this.processors = processors.stream()
            .collect(Collectors.toMap(
                this::getPaymentMethod,
                Function.identity()
            ));
        this.paymentRepository = paymentRepository;
    }

    public PaymentResult processPayment(PaymentRequest request) {
        PaymentProcessor processor = processors.get(request.getPaymentMethod());
        if (processor == null) {
            return PaymentResult.failure("Unsupported payment method");
        }

        PaymentResult result = processor.processPayment(request);

        // Save payment record
        Payment payment = new Payment(
            request.getTicketId(),
            request.getAmount(),
            request.getPaymentMethod(),
            result.getTransactionId(),
            result.isSuccessful()
        );
        paymentRepository.save(payment);

        return result;
    }
}

โšก Electric Vehicle Charging System

public enum ChargingStandard {
    TYPE1(120, "Type 1 (J1772)"),
    TYPE2(240, "Type 2 (Mennekes)"),
    CCS(480, "CCS (Combined Charging System)"),
    CHADEMO(480, "CHAdeMO"),
    TESLA_SUPERCHARGER(480, "Tesla Supercharger");

    private final int maxPower;
    private final String description;

    ChargingStandard(int maxPower, String description) {
        this.maxPower = maxPower;
        this.description = description;
    }

    // Getters...
}

public class ChargingStation {
    private final String stationId;
    private final String spotId;
    private final Set<ChargingStandard> supportedStandards;
    private final int maxPowerKw;
    private ChargingSession currentSession;
    private boolean isOperational;
    private LocalDateTime lastMaintenance;

    public ChargingStation(String stationId, String spotId, 
                          Set<ChargingStandard> supportedStandards, int maxPowerKw) {
        this.stationId = stationId;
        this.spotId = spotId;
        this.supportedStandards = supportedStandards;
        this.maxPowerKw = maxPowerKw;
        this.isOperational = true;
        this.lastMaintenance = LocalDateTime.now();
    }

    public boolean startCharging(String ticketId, ChargingStandard standard, 
                               PaymentMethod paymentMethod) {
        if (!isAvailable() || !supportedStandards.contains(standard)) {
            return false;
        }

        this.currentSession = new ChargingSession(
            ticketId, 
            standard, 
            paymentMethod,
            LocalDateTime.now()
        );

        logger.info("Charging started at station {} for ticket {}", 
                   stationId, ticketId);
        return true;
    }

    public ChargingSession stopCharging() {
        if (currentSession != null) {
            currentSession.endSession();
            ChargingSession completedSession = currentSession;
            currentSession = null;

            logger.info("Charging stopped at station {}. Duration: {} minutes, Energy: {} kWh",
                       stationId, 
                       completedSession.getDurationMinutes(),
                       completedSession.getEnergyDelivered());

            return completedSession;
        }
        return null;
    }

    public boolean isAvailable() {
        return isOperational && currentSession == null;
    }

    public ChargingStatus getStatus() {
        if (!isOperational) {
            return ChargingStatus.OUT_OF_ORDER;
        }
        if (currentSession == null) {
            return ChargingStatus.AVAILABLE;
        }
        return ChargingStatus.CHARGING;
    }
}

public class ChargingSession {
    private final String ticketId;
    private final ChargingStandard standard;
    private final PaymentMethod paymentMethod;
    private final LocalDateTime startTime;
    private LocalDateTime endTime;
    private BigDecimal energyDelivered; // kWh
    private BigDecimal cost;

    public ChargingSession(String ticketId, ChargingStandard standard, 
                          PaymentMethod paymentMethod, LocalDateTime startTime) {
        this.ticketId = ticketId;
        this.standard = standard;
        this.paymentMethod = paymentMethod;
        this.startTime = startTime;
        this.energyDelivered = BigDecimal.ZERO;
    }

    public void endSession() {
        this.endTime = LocalDateTime.now();
        this.cost = calculateChargingCost();
    }

    private BigDecimal calculateChargingCost() {
        // $0.30 per kWh base rate
        BigDecimal ratePerKwh = new BigDecimal("0.30");
        return energyDelivered.multiply(ratePerKwh);
    }

    public long getDurationMinutes() {
        LocalDateTime end = endTime != null ? endTime : LocalDateTime.now();
        return Duration.between(startTime, end).toMinutes();
    }

    // Getters and setters...
}

@Service
public class ChargingStationService {
    private final Map<String, ChargingStation> stations = new ConcurrentHashMap<>();
    private final PaymentService paymentService;

    public ChargingStationService(PaymentService paymentService) {
        this.paymentService = paymentService;
        initializeChargingStations();
    }

    private void initializeChargingStations() {
        // Initialize charging stations for electric spots
        for (int floor = 1; floor <= 3; floor++) {
            for (int i = 1; i <= 8; i++) {
                String spotId = String.format("F%d-E%02d", floor, i);
                String stationId = "CHG-" + spotId;

                Set<ChargingStandard> standards = Set.of(
                    ChargingStandard.TYPE2,
                    ChargingStandard.CCS
                );

                ChargingStation station = new ChargingStation(
                    stationId, spotId, standards, 50
                );
                stations.put(stationId, station);
            }
        }
    }

    public Optional<ChargingStation> findAvailableStation() {
        return stations.values().stream()
            .filter(ChargingStation::isAvailable)
            .findFirst();
    }

    public boolean startCharging(String stationId, String ticketId, 
                               ChargingStandard standard, PaymentMethod paymentMethod) {
        ChargingStation station = stations.get(stationId);
        if (station == null) {
            return false;
        }

        return station.startCharging(ticketId, standard, paymentMethod);
    }

    public BigDecimal stopChargingAndCalculateCost(String stationId) {
        ChargingStation station = stations.get(stationId);
        if (station == null) {
            return BigDecimal.ZERO;
        }

        ChargingSession session = station.stopCharging();
        return session != null ? session.getCost() : BigDecimal.ZERO;
    }
}

๐Ÿ“Š Real-Time Display System

@Component
public class DisplayBoardService {
    private final ParkingSpotService parkingSpotService;
    private final ChargingStationService chargingStationService;

    @Scheduled(fixedRate = 5000) // Update every 5 seconds
    public void updateDisplayBoards() {
        DisplayData displayData = generateDisplayData();
        broadcastToDisplays(displayData);
    }

    private DisplayData generateDisplayData() {
        Map<Integer, Map<SpotType, Long>> availabilityByFloor = 
            parkingSpotService.getAvailabilityByFloor();

        long availableChargingStations = chargingStationService
            .getAllStations()
            .stream()
            .mapToLong(station -> station.isAvailable() ? 1 : 0)
            .sum();

        return new DisplayData(
            availabilityByFloor,
            availableChargingStations,
            LocalDateTime.now()
        );
    }

    private void broadcastToDisplays(DisplayData data) {
        // Send to entry displays
        displayControllerService.updateEntryDisplays(data);

        // Send to floor displays
        for (int floor = 1; floor <= 3; floor++) {
            displayControllerService.updateFloorDisplay(floor, data);
        }

        // Send to mobile app via WebSocket
        webSocketService.broadcastAvailability(data);
    }
}

public class DisplayData {
    private final Map<Integer, Map<SpotType, Long>> availabilityByFloor;
    private final long availableChargingStations;
    private final LocalDateTime lastUpdate;

    public DisplayData(Map<Integer, Map<SpotType, Long>> availabilityByFloor,
                      long availableChargingStations, LocalDateTime lastUpdate) {
        this.availabilityByFloor = availabilityByFloor;
        this.availableChargingStations = availableChargingStations;
        this.lastUpdate = lastUpdate;
    }

    public String generateDisplayText() {
        StringBuilder display = new StringBuilder();
        display.append("=== PARKING AVAILABILITY ===\n");

        availabilityByFloor.forEach((floor, spots) -> {
            display.append(String.format("FLOOR %d: ", floor));
            spots.forEach((type, count) -> {
                String emoji = getEmojiForSpotType(type);
                display.append(String.format("%s %d  ", emoji, count));
            });
            display.append("\n");
        });

        display.append(String.format("โšก CHARGING: %d AVAILABLE\n", availableChargingStations));
        display.append(String.format("Updated: %s", 
                      lastUpdate.format(DateTimeFormatter.ofPattern("HH:mm:ss"))));

        return display.toString();
    }

    private String getEmojiForSpotType(SpotType type) {
        return switch (type) {
            case COMPACT -> "๐Ÿš—";
            case LARGE -> "๐Ÿš™";
            case HANDICAPPED -> "โ™ฟ";
            case MOTORCYCLE -> "๐Ÿ๏ธ";
            case ELECTRIC -> "โšก";
        };
    }

    // Getters...
}

๐ŸŽฏ Main Parking Lot Controller

@RestController
@RequestMapping("/api/parking")
public class ParkingLotController {
    private final TicketService ticketService;
    private final ParkingSpotService parkingSpotService;
    private final PaymentService paymentService;
    private final ChargingStationService chargingStationService;

    @PostMapping("/entry")
    public ResponseEntity<EntryResponse> enterParkingLot(
            @RequestBody EntryRequest request) {

        try {
            // Find available spot
            Optional<ParkingSpot> availableSpot = 
                parkingSpotService.findAvailableSpot(request.getVehicleType());

            if (availableSpot.isEmpty()) {
                return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                    .body(new EntryResponse("No available spots", null));
            }

            ParkingSpot spot = availableSpot.get();

            // Issue ticket
            Ticket ticket = ticketService.issueTicket(
                request.getVehicleType(), 
                spot.getSpotId()
            );

            // Occupy spot
            if (spot.occupy(ticket.getTicketId())) {
                // For electric vehicles, also reserve charging station
                if (request.getVehicleType() == VehicleType.ELECTRIC_CAR) {
                    Optional<ChargingStation> station = 
                        chargingStationService.findAvailableStation();
                    if (station.isPresent()) {
                        ticket.setChargingStationId(station.get().getStationId());
                    }
                }

                return ResponseEntity.ok(new EntryResponse(
                    "Welcome! Proceed to " + spot.getSpotId(),
                    ticket
                ));
            } else {
                return ResponseEntity.status(HttpStatus.CONFLICT)
                    .body(new EntryResponse("Spot assignment failed", null));
            }

        } catch (Exception e) {
            logger.error("Entry processing failed", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new EntryResponse("System error", null));
        }
    }

    @PostMapping("/payment")
    public ResponseEntity<PaymentResponse> processPayment(
            @RequestBody PaymentRequest request) {

        try {
            BigDecimal fee = ticketService.calculateFee(request.getTicketId());
            request.setAmount(fee);

            PaymentResult result = paymentService.processPayment(request);

            if (result.isSuccessful()) {
                return ResponseEntity.ok(new PaymentResponse(
                    "Payment successful",
                    result.getTransactionId(),
                    fee
                ));
            } else {
                return ResponseEntity.badRequest()
                    .body(new PaymentResponse(result.getErrorMessage(), null, fee));
            }

        } catch (TicketNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            logger.error("Payment processing failed", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new PaymentResponse("Payment system error", null, null));
        }
    }

    @PostMapping("/exit")
    public ResponseEntity<ExitResponse> exitParkingLot(
            @RequestBody ExitRequest request) {

        try {
            Ticket ticket = ticketService.getTicket(request.getTicketId());

            if (!ticket.isPaid()) {
                return ResponseEntity.badRequest()
                    .body(new ExitResponse("Payment required before exit", false));
            }

            // Free up the parking spot
            ParkingSpot spot = parkingSpotService.getSpot(ticket.getSpotId());
            spot.vacate();

            // Stop charging if applicable
            if (ticket.getChargingStationId() != null) {
                BigDecimal chargingCost = chargingStationService
                    .stopChargingAndCalculateCost(ticket.getChargingStationId());

                if (chargingCost.compareTo(BigDecimal.ZERO) > 0) {
                    // Additional charging payment may be required
                    // This could be handled separately or added to parking fee
                }
            }

            // Mark ticket as used
            ticketService.completeTicket(request.getTicketId());

            return ResponseEntity.ok(new ExitResponse(
                "Thank you for parking with us! Have a great day!", 
                true
            ));

        } catch (Exception e) {
            logger.error("Exit processing failed", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new ExitResponse("Exit system error", false));
        }
    }

    @GetMapping("/availability")
    public ResponseEntity<Map<SpotType, Long>> getAvailability() {
        return ResponseEntity.ok(parkingSpotService.getAvailabilityByType());
    }

    @GetMapping("/status/{ticketId}")
    public ResponseEntity<TicketStatus> getTicketStatus(@PathVariable String ticketId) {
        try {
            Ticket ticket = ticketService.getTicket(ticketId);
            BigDecimal currentFee = ticketService.calculateFee(ticketId);

            return ResponseEntity.ok(new TicketStatus(
                ticket.getTicketId(),
                ticket.getSpotId(),
                ticket.getParkingDuration(),
                currentFee,
                ticket.isPaid()
            ));
        } catch (TicketNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }
}

These examples demonstrate:

โœ… Clean Architecture - Separation of concerns with services, controllers, and domain models
โœ… Type Safety - Using enums and strong typing throughout
โœ… Concurrency - Thread-safe operations with proper synchronization
โœ… Error Handling - Comprehensive exception handling and logging
โœ… Scalability - Modular design that can be easily extended
โœ… Real-world Patterns - Repository pattern, dependency injection, and RESTful APIs

The code shows how to implement all the key features we discussed, from basic parking operations to advanced features like EV charging integration!


๐Ÿ“š Additional Resources