Application: Parking Lot Payment System
Design a parking lot system where vehicles park in spots and payment is calculated based on vehicle type and duration. We need to handle different vehicle types and multiple payment methods.
Use Inheritance for Vehicle Types: Different vehicles (Car, Motorcycle, Truck) share common attributes (license plate, entry time) but have type-specific pricing rules. They are legitimately different types of the same concept.
Use Composition for Payment Processing: A ParkingTicket should not "be a" payment method. Instead, it should "have a" payment strategy that can be swapped. This allows runtime flexibility to handle cash, card, or digital wallet payments.
- entryTime: DateTime
+ getSpotSize(): SpotSize
getSpotSize(): COMPACT
getSpotSize(): SMALL
getSpotSize(): LARGE
- paymentStrategy: PaymentStrategy
- exitTime: DateTime
+ processPayment(): Receipt
calculateChange()
authorizeCard()
verifyBalance()
First, inheritance for vehicles is appropriate because a Car truly "is a" Vehicle, and all vehicle types share core parking behavior while overriding type-specific details like fee calculation.
Second, composition for payment allows the ParkingTicket to switch payment methods at runtime without changing its type. A ticket does not "become" a cash payment; it uses a cash payment strategy.
Third, if we incorrectly used inheritance for payments (CashTicket, CardTicket), we would need separate ticket classes for each payment type, violating the Single Responsibility Principle (SRP) and creating a combinatorial explosion of classes.