Bird
Raised Fist0

Design an Online Shopping Cart - Product, Cart, Order, Discount, Coupon OOP

LLDmediumInterview freq: high
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/3
Product abstract class

Product is an abstract class holding shared state like id and name and behavior getPrice().

🎯 Tests whether candidate knows abstract class is correct because Product holds instance state which interfaces cannot hold in Java.
public abstract class Product {
    protected String id;
    protected String name;
    public abstract double getPrice();
}
Cart composition with CartItem

Cart has a composition relationship with CartItem, owning its lifecycle and managing a list of items.

🎯 Tests whether candidate understands composition lifecycle: CartItem cannot exist independently without Cart.
public class Cart {
    private List<CartItem> items = new ArrayList<>();
    public synchronized void addItem(Product p, int quantity) {
        items.add(new CartItem(p, quantity));
    }
}
Discount abstract class and PercentageDiscount realization

Discount is an abstract class defining apply() method; PercentageDiscount extends it providing concrete implementation.

🎯 Tests whether candidate recognizes Strategy pattern realization via abstract class and subclass, enabling OCP for discount types.
public abstract class Discount {
    public abstract double apply(double amount);
}
public class PercentageDiscount extends Discount {
    private double percent;
    public PercentageDiscount(double percent) {
        this.percent = percent;
    }
    public double apply(double amount) {
        return amount * (1 - percent / 100);
    }
}
📐
Class Diagram
Class Diagram
       +----------------+
       | <<Abstract>>   |
       |   Product      |
       +----------------+
       | -id: String    |
       | -name: String  |
       +----------------+
       | +getPrice():   |
       |   double       |
       +----------------+
              │
              │ extends
              │
       +----------------+
       |   CartItem     |
       +----------------+
       | -product:Product|
       | -quantity:int  |
       +----------------+
       | +getTotalPrice():|
       |   double       |
       +----------------+
              │
              │ composition ◆
              │
       +----------------+
       |     Cart       |
       +----------------+
       | -items: List<  |
       |   CartItem>    |
       +----------------+
       | +addItem(p,q): |
       |   void [sync]  |
       | +getTotal():   |
       |   double       |
       +----------------+
              │
              │ association ──►
              │
       +----------------+
       |   Discount     |
       | <<Abstract>>   |
       +----------------+
       | +apply(double):|
       |   double       |
       +----------------+
              │
              │ extends
              │
       +----------------+
       |PercentageDisc. |
       +----------------+
       | -percent: double|
       +----------------+
       | +apply(double): |
       |   double       |
       +----------------+

This class diagram illustrates key Java OOP design decisions for an online shopping cart system. Product is an abstract class because it holds shared instance state like id and name, which interfaces cannot hold in Java. Cart composes CartItem, enforcing strong lifecycle ownership, meaning CartItem cannot exist independently, demonstrating composition. Discount is an abstract class representing the Strategy pattern; PercentageDiscount realizes it, allowing extension without modifying existing code, adhering to the Open-Closed Principle. The diagram uses composition (◆) for Cart-CartItem, association (──►) for Cart-Discount, and inheritance (│ extends) for class hierarchies, emphasizing Java-specific design choices.

Primary Focus

✓ Abstract class vs Interface + Composition lifecycle + Strategy pattern realization

Practice

(1/5)
1. In designing a notification channel abstraction, should NotificationChannel be an abstract class or an interface? Consider that each channel has state like connection status and common methods like connect() and send(). Why?
easy
A. Abstract class, because it can hold shared state and provide default method implementations.
B. Abstract class, because interfaces cannot define method signatures.
C. Interface, because Java interfaces can now have default methods with state variables.
D. Interface, because it allows multiple inheritance and all methods are stateless contracts.

Solution

  1. Step 1: Analyze state and behavior requirements

    NotificationChannel needs to hold connection status (state) and provide common method implementations.
  2. Step 2: Choose between interface and abstract class

    Interfaces cannot hold instance state; abstract classes can hold state and provide default behavior, making abstract class the correct choice.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Abstract class supports shared state and default methods [check]
Hint: Stateful base -> abstract class; stateless contract -> interface [check]
Common Mistakes:
2. You want to add a WeekendFeeStrategy to calculate parking fees differently on weekends. Given the current design uses a FeeStrategy interface, what is the minimum change to comply with SOLID principles?
medium
A. Modify the existing FeeStrategy implementation to add weekend logic with an if-else block.
B. Merge all fee strategies into a single class with multiple methods for each pricing rule.
C. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it where needed without modifying existing classes.
D. Add a boolean flag isWeekend to the ParkingLot class and change fee calculation accordingly.

Solution

  1. Step 1: Identify SOLID principle

    Open-Closed Principle (OCP) requires classes to be open for extension but closed for modification.
  2. Step 2: Apply OCP

    Creating a new WeekendFeeStrategy class extends functionality without modifying existing code, adhering to OCP and Dependency Inversion Principle.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    New strategy class -> extend without modifying existing -> OCP [check]
Hint: Add new strategy class, don't modify existing code [check]
Common Mistakes:
3. The ATM system currently calculates transaction fees using a FeeCalculator class. To add a WeekendFeeStrategy without modifying existing classes, which SOLID principle applies and what is the minimal correct change?
medium
A. Add a boolean flag isWeekend in FeeCalculator and branch logic accordingly, maintaining SRP.
B. Modify FeeCalculator to add weekend logic, violating OCP but keeping code simple.
C. Create WeekendFeeStrategy implementing FeeStrategy interface; FeeCalculator uses FeeStrategy via dependency injection, adhering to OCP and DIP.
D. Create WeekendFeeStrategy subclassing FeeCalculator and override fee calculation, violating DIP.

Solution

  1. Step 1: Identify applicable SOLID principles

    Open-Closed Principle (OCP) requires FeeCalculator not be modified for new fee types. Dependency Inversion Principle (DIP) requires FeeCalculator depend on abstractions.
  2. Step 2: Apply correct design

    Create WeekendFeeStrategy implementing FeeStrategy interface. Inject FeeStrategy into FeeCalculator. This adds new behavior without modifying existing code.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    New strategy class + DI -> OCP and DIP respected [check]
Hint: New fee? Add strategy class, inject via interface [check]
Common Mistakes:
4. You want to add a WeekendFeeStrategy to calculate weekend parking fees without modifying existing classes. Which SOLID principle guides the minimum change, and what is the correct approach?
medium
A. Modify the ParkingLot class to add weekend fee logic, enforcing Single Responsibility Principle.
B. Add weekend fee logic inside existing FeeStrategy implementations, following Dependency Inversion Principle.
C. Create a WeekendFeeStrategy subclass of ParkingLot to override fee calculation, following Liskov Substitution Principle.
D. Create a new WeekendFeeStrategy class implementing FeeStrategy interface, and inject it where needed, following Open/Closed Principle.

Solution

  1. Step 1: Identify the SOLID principle for extensibility

    Open/Closed Principle (OCP) requires adding new functionality without modifying existing code.
  2. Step 2: Evaluate approaches

    Creating a new FeeStrategy implementation and injecting it respects OCP and DIP; modifying ParkingLot or existing strategies violates OCP or mixes responsibilities.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    New FeeStrategy class + injection -> OCP and DIP respected [check]
Hint: New strategy class + injection -> Open/Closed Principle [check]
Common Mistakes:
5. The notification system must support ElectricCar vehicles that require ChargingSpot notifications. What is the minimum design change to support this without modifying existing classes?
hard
A. Modify Vehicle class to add isElectric flag and add charging logic in existing Spot classes.
B. Create a new ElectricCar class and ChargingSpot class, then modify NotificationFactory to handle them.
C. Add ELECTRIC_CAR to VehicleType enum and CHARGING to SpotType enum; create ElectricCar subclass and update SpotCompatibility map.
D. Add charging logic inside existing NotificationChannel implementations with conditional checks for ElectricCar.

Solution

  1. Step 1: Identify extensibility requirements

    New vehicle and spot types must be added without modifying existing classes to respect OCP.
  2. Step 2: Apply minimal changes

    Adding new enum values and creating new subclasses allows extension without modifying existing class code; updating compatibility map centralizes new logic.
  3. Step 3: Eliminate other options

    Options B, C, and D modify existing classes or factory logic, violating OCP and risking class explosion or god-class anti-pattern.
  4. Final Answer:

    Option C -> Option C
  5. Quick Check:

    New enums and subclasses extend design without modifying existing classes [check]
Hint: Add enums + subclasses, avoid modifying existing classes [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard