Design an online shopping system like Amazon. What are the core classes?
Fast recall
Quick revision
Core answer
Ability to decompose a complex domain into cohesive classes with clear responsibilities, understanding entity relationships, and recognizing the difference between transactional and catalog data
Creating a god class Order that contains everything from product details to payment logic, or storing inventory counts directly in Product class, or mixing authentication concerns with business domain entities
Explicitly explain the separation: Cart is ephemeral session state while Order is persistent transaction, Product is catalog metadata while Inventory tracks physical stock, and Address is reusable across multiple orders as a value object
Interview-ready guide
Interview answer
Because an Amazon-style system is so broad, I'd organise it into layers rather than rattle off twenty classes. There's a catalog layer with Product and ProductCatalog, a cart layer with Cart and CartItem, an order layer with Order and OrderItem plus an order state machine, and a payment layer with Payment and a PaymentProcessor. User and Address cut across all of them.
The relationship I'd highlight is the cart-to-order conversion. A Cart holds CartItems, where each CartItem is a live reference to a Product plus a quantity. At checkout, the cart converts into an Order made up of OrderItems. The crucial detail is that an OrderItem snapshots the price at the moment of purchase rather than pointing at the product's current price. Otherwise, when the catalog price changes next week, it would silently rewrite the totals on orders people already placed. An order is a historical record, so it has to be immutable in that sense.
From there I'd add behaviour with patterns. The order lifecycle — placed, processing, shipped, delivered, cancelled — is a natural State pattern, where each state only allows valid transitions. And payment is a Strategy, since there are many payment methods behind one interface. The main mistakes I'd avoid are building one God class that does everything, and forgetting that checkout is a real boundary where a mutable cart becomes an immutable order.
Design an online shopping system like Amazon. What are the core classes
Direct Answer
Core classes include User (customer profile and credentials), Product (catalog item with name, price, description), ProductCatalog (search and browse operations), Cart (shopping basket tied to user session), CartItem (product reference plus quantity), Order (completed purchase with status), OrderItem (line item in order), Payment (transaction record), Address (shipping and billing locations), Review (customer ratings), and Inventory (stock levels separate from catalog). These classes model the complete flow from product discovery through checkout to fulfillment.
Deep Dive & Architecture
Catalogue and inventory answer different questions
Product describes what is sold. Inventory records how much of a product is available or reserved at a warehouse. User, Address, Cart, and CartItem represent shopping before checkout; cart prices are suggestions because catalogue prices can change.
Checkout creates a historical snapshot
At checkout, the service validates price and stock, reserves inventory, and creates an Order with immutable OrderItem snapshots containing product id, name, unit price, quantity, tax, and discount used for that purchase. Later catalogue edits must not rewrite an old receipt.
Payment and fulfilment have separate lifecycles
PaymentAttempt records gateway requests and idempotency keys. Shipment tracks fulfilment and can be split when items leave different warehouses. OrderStatus controls customer-visible progress, while inventory reservation, payment confirmation, cancellation, and release operations must be safe to retry. Walking one checkout and one failure path is more useful than placing every e-commerce feature into one class diagram.
Code Example
class Product {
private final String id; private String name; private BigDecimal price;
}
class CartItem {
private final Product product; private int quantity; // live reference
}
class Cart {
private final List<CartItem> items = new ArrayList<>();
Order checkout(User user) { // convert to order
List<OrderItem> lines = items.stream()
.map(ci -> new OrderItem(ci.product().id(), ci.quantity(),
ci.product().price())) // SNAPSHOT price now
.toList();
return new Order(UUID.randomUUID().toString(), user, lines, OrderStatus.PLACED);
}
}
record OrderItem(String productId, int quantity, BigDecimal priceAtPurchase) {}
class Order {
private final String id; private final User user;
private final List<OrderItem> items; private OrderStatus status;
Order(String id, User u, List<OrderItem> i, OrderStatus s){ this.id=id; user=u; items=i; status=s; }
}
OrderItem snapshots the price so later catalog changes don't rewrite order history.
Common Mistakes & Pitfalls
- OrderItem referencing live price — if it points to
Product.price, a later price change rewrites past orders. Snapshot it. - One giant
ShoppingSystemclass — group into catalog/cart/order/payment layers (SRP). - No Cart→Order boundary — checkout is the moment the mutable cart becomes an immutable order.
- Skipping order status — orders need a state machine (placed → shipped → delivered).
Check your understanding
Answer these without looking back at the article.
- How do you design the product review and rating system?
- How do you design the order state machine in the shopping system?
- How do you design the inventory management component?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.